def test_sync_remove_team_shared_folder(self): params = get_synced_params() teams_to_delete = [x['team_uid'] for x in params.team_cache.values()] sf_to_delete = [ x['shared_folder_uid'] for x in params.shared_folder_cache.values() ] def sync_down_removed_teams_and_shared_folders(rq): self.assertEqual(rq['command'], 'sync_down') return { 'revision': vault_env.revision + 1, 'removed_shared_folders': sf_to_delete, 'removed_teams': teams_to_delete } KeeperApiHelper.communicate_expect( [sync_down_removed_teams_and_shared_folders]) sync_down(params) self.assertTrue(KeeperApiHelper.is_expect_empty()) self.assertEqual(len(params.record_cache), 2) self.assertEqual(len(params.shared_folder_cache), 0) self.assertEqual(len(params.team_cache), 0) self.assert_key_unencrypted(params)
def test_convert_to_folders(self): params = get_synced_params() KeeperApiHelper.communicate_expect(['convert_to_folders']) result = convert_to_folders(params) self.assertTrue(KeeperApiHelper.is_expect_empty()) self.assertTrue(result)
def test_move_success(self): params = get_synced_params() cmd = folder.FolderMoveCommand() user_folder = next( iter([ x for x in params.folder_cache.values() if x.type == 'user_folder' ])) shared_folder = next( iter([ x for x in params.folder_cache.values() if x.type == 'shared_folder' ])) root_record_uid = next(iter(params.subfolder_record_cache[''])) sf_record_uid = next( iter(params.subfolder_record_cache[shared_folder.uid])) KeeperApiHelper.communicate_expect(['move']) cmd.execute(params, src=root_record_uid, dst=user_folder.uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect(['move']) cmd.execute(params, src=sf_record_uid, dst=user_folder.name) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect(['move']) cmd.execute(params, src=root_record_uid, dst=user_folder.uid) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_accept_account_transfer_consent(self): params = get_connected_params() share_account_to = [{ 'role_id': 123456789, 'public_key': vault_env.encoded_public_key }] with mock.patch('builtins.print'), mock.patch('builtins.input', return_value='accept'): KeeperApiHelper.communicate_expect(['share_account']) self.assertTrue( api.accept_account_transfer_consent(params, share_account_to)) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_delete_attachment_command(self): params = get_synced_params() cmd = recordv2.RecordDeleteAttachmentCommand() record_uid = next( iter([ x['record_uid'] for x in params.record_cache.values() if len(x['extra_unencrypted']) > 10 ])) rec = api.get_record(params, record_uid) KeeperApiHelper.communicate_expect(['record_update']) cmd.execute(params, name=[rec.attachments[0]['id']], record=rec.title) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_accept_account_transfer_consent(self): params = get_connected_params() params.settings = { 'must_perform_account_share_by': '1632370067000', 'share_account_to': [{ 'role_id': 123456789, 'public_key': vault_env.encoded_public_key }] } with mock.patch('builtins.print'), mock.patch('builtins.input', return_value='accept'): KeeperApiHelper.communicate_expect(['share_account']) self.assertTrue(api.accept_account_transfer_consent(params)) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_add_command_check_request(self): params = get_synced_params() cmd = record.RecordAddCommand() def check_record(rq): rq['command'] = 'record_add' record_key = api.decrypt_data(rq['record_key'], self.vault_env.data_key) data_bytes = api.decrypt_data(rq['data'], record_key) data = json.loads(data_bytes.decode('utf-8')) self.assertEqual(data['title'], 'data') self.assertEqual(data['title'], data['link']) self.assertEqual(data['secret1'], data['secret2']) self.assertEqual(len(data['custom']), 2) with mock.patch('builtins.input', return_value='data'): KeeperApiHelper.communicate_expect([check_record]) cmd.execute(params, custom='name1: value 1, name2: value 2') self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_sync_remove_owned_records(self): params = get_synced_params() len_before = len(params.record_cache) records_to_delete = [x['record_uid'] for x in params.meta_data_cache.values() if x['owner']] def sync_down_removed_records(rq): self.assertEqual(rq['command'], 'sync_down') return { 'revision': vault_env.revision + 1, 'removed_records': records_to_delete } KeeperApiHelper.communicate_expect([sync_down_removed_records]) sync_down(params) self.assertTrue(KeeperApiHelper.is_expect_empty()) self.assertEqual(len(params.record_cache), len_before - len(records_to_delete)) self.assert_key_unencrypted(params)
def test_team_list_command(self): params = get_synced_params() cmd = record.RecordListTeamCommand() def get_available_teams(rq): self.assertEqual(rq['command'], 'get_available_teams') return { 'teams': [{ 'team_uid': api.generate_record_uid(), 'team_name': 'Team 1' }, { 'team_uid': api.generate_record_uid(), 'team_name': 'Team 2' }] } KeeperApiHelper.communicate_expect([get_available_teams]) with mock.patch('builtins.print'): cmd.execute(params) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_delete_shared_folder(self): params = get_synced_params() cmd = folder.FolderRemoveCommand() shared_folder = next( iter([ x for x in params.folder_cache.values() if x.type == 'shared_folder' ])) def shared_folder_update(rq): requests = [{ 'command': 'shared_folder_update', 'operation': 'delete', 'shared_folder_uid': shared_folder.uid }] self.assertEqual(rq['command'], 'execute') self.assertEqual(rq['requests'], requests) KeeperApiHelper.communicate_expect([shared_folder_update]) cmd.execute(params, force=True, pattern=[shared_folder.name]) self.assertTrue(KeeperApiHelper.is_expect_empty()) with mock.patch( 'keepercommander.commands.folder.user_choice') as mock_choice: mock_choice.return_value = 'y' KeeperApiHelper.communicate_expect([shared_folder_update]) cmd.execute(params, pattern=[shared_folder.name]) self.assertTrue(KeeperApiHelper.is_expect_empty()) mock_choice.return_value = 'n' cmd.execute(params, pattern=[shared_folder.name])
def test_delete_user_folder(self): params = get_synced_params() cmd = folder.FolderRemoveCommand() user_folder = next( iter([ x for x in params.folder_cache.values() if x.type == 'user_folder' ])) def pre_delete(rq): self.assertEqual(rq['command'], 'pre_delete') return { 'pre_delete_response': { 'would_delete': { 'deletion_summary': ['1 Personal Folder'] }, 'pre_delete_token': 'token' } } with mock.patch('builtins.print'), mock.patch( 'keepercommander.commands.folder.user_choice') as mock_choice: mock_choice.return_value = 'n' KeeperApiHelper.communicate_expect([pre_delete]) cmd.execute(params, pattern=[user_folder.name]) self.assertTrue(KeeperApiHelper.is_expect_empty()) mock_choice.return_value = 'y' KeeperApiHelper.communicate_expect([pre_delete, 'delete']) cmd.execute(params, pattern=[user_folder.name]) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_change_password(self): params = get_connected_params() with mock.patch('keepercommander.rest_api.get_new_user_params' ) as m_params, mock.patch( 'builtins.print'), mock.patch( 'getpass.getpass') as m_getpass: user_params = APIRequest_pb2.NewUserMinimumParams() user_params.minimumIterations = 1000 user_params.passwordMatchRegex.extend( ['^(?=(.*[A-Z]){1,}).*$', '^(?=(.*[0-9]){2,}).*$', '.{6,}']) user_params.passwordMatchDescription.extend([ 'Contains at least 1 uppercase character(s)', 'Contains at least 2 digit(s)', 'At least 6 character(s)' ]) m_params.return_value = user_params m_getpass.return_value = '1New2Password3' KeeperApiHelper.communicate_expect(['change_master_password']) self.assertTrue(api.change_master_password(params)) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_download_attachment_command(self): params = get_synced_params() cmd = record.RecordDownloadAttachmentCommand() records = [ x for x in params.record_cache.values() if len(x['extra_unencrypted']) > 10 ] rec = records[0] record_uid = rec['record_uid'] extra = json.loads(rec['extra_unencrypted'].decode('utf-8')) attachments = {} for file in extra['files']: key = base64.urlsafe_b64decode(file['key'] + '==') body_encoded = api.encrypt_aes(os.urandom(file['size']), key) attachments['https://keepersecurity.com/files/' + file['id']] = body_encoded def request_download(rq): self.assertEqual(rq['command'], 'request_download') return { 'downloads': [{ 'url': 'https://keepersecurity.com/files/' + x } for x in rq['file_ids']] } def request_http_get(url, **kwargs): attachment = mock.Mock() attachment.raw = io.BytesIO( base64.urlsafe_b64decode(attachments[url] + '==')) return attachment with mock.patch('requests.get', side_effect=request_http_get) as mock_get, \ mock.patch('builtins.open', mock.mock_open()), mock.patch('os.path.abspath', return_value='/file_name') as mock_abspath: KeeperApiHelper.communicate_expect([request_download]) cmd.execute(params, record=record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) mock_get.assert_called() mock_abspath.assert_called()
def test_upload_attachment_command(self): params = get_synced_params() cmd = recordv2.RecordUploadAttachmentCommand() record_uid = next( iter([ x['record_uid'] for x in params.record_cache.values() if len(x['extra_unencrypted']) > 10 ])) rec = api.get_record(params, record_uid) with self.assertRaises(CommandError): cmd.execute(params, record=rec.title) def request_upload(rq): self.assertEqual(rq['command'], 'request_upload') return { 'file_uploads': [{ 'max_size': 1000000, 'url': 'https://keepersecurity.com/uploads/', 'success_status_code': 201, 'file_id': 'ABCDEF%.2d' % x, 'file_parameter': 'file', 'parameters': { 'a': 'b' } } for x in range((rq.get('file_count') or 0) + (rq.get('thumbnail_count') or 0))] } def request_http_post(url, **kwargs): attachment = mock.Mock() attachment.status_code = 201 return attachment with mock.patch('requests.post', side_effect=request_http_post), \ mock.patch('builtins.open', mock.mock_open(read_data=b'data')) as m_open, \ mock.patch('os.path.isfile', return_value=True), \ mock.patch('os.path.getsize') as mock_getsize: m_open.return_value.tell = lambda: 4 mock_getsize.return_value = 1000000000 with self.assertRaises(CommandError): KeeperApiHelper.communicate_expect([request_upload]) cmd.execute(params, file=['file.data'], record=record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect( [request_upload, 'record_update']) m_open.return_value.tell = lambda: 4 mock_getsize.return_value = 1000 cmd.execute(params, file=['file.data'], record=record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_enterprise_invite(self): params = get_connected_params() params.enforcements = {'enterprise_invited': 'Test Enterprise'} cmd = utils.CheckEnforcementsCommand() with mock.patch('builtins.print'), mock.patch( 'keepercommander.commands.utils.user_choice' ) as m_choice, mock.patch('builtins.input') as m_input: # accept, enter invite code def accept_enterprise_invite(rq): self.assertEqual(rq['command'], 'accept_enterprise_invite') self.assertEqual(rq['verification_code'], TestRegister.enterpriseInviteCode) m_choice.return_value = 'Accept' m_input.return_value = TestRegister.enterpriseInviteCode KeeperApiHelper.communicate_expect([accept_enterprise_invite]) cmd.execute(params) self.assertTrue(KeeperApiHelper.is_expect_empty()) # accept, skip invite code m_choice.return_value = 'Accept' m_input.return_value = '' cmd.execute(params) # decline m_choice.return_value = 'Decline' m_input.side_effect = KeyboardInterrupt() KeeperApiHelper.communicate_expect(['decline_enterprise_invite']) cmd.execute(params) self.assertTrue(KeeperApiHelper.is_expect_empty()) # ignore m_choice.return_value = 'Ignore' cmd.execute(params)
def test_remove_command_from_root(self): params = get_synced_params() cmd = recordv2.RecordRemoveCommand() record_uid = next(iter(params.subfolder_record_cache[''])) rec = api.get_record(params, record_uid) def pre_delete_command(rq): self.assertEqual(rq['command'], 'pre_delete') return { 'pre_delete_response': { 'would_delete': { 'deletion_summary': ['delete all'] }, 'pre_delete_token': 'token' } } with mock.patch('keepercommander.commands.recordv2.user_choice' ) as choice_mock: choice_mock.return_value = KeyboardInterrupt() KeeperApiHelper.communicate_expect([pre_delete_command, 'delete']) cmd.execute(params, force=True, record=rec.record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect([pre_delete_command, 'delete']) cmd.execute(params, force=True, record=rec.title) self.assertTrue(KeeperApiHelper.is_expect_empty()) with mock.patch('builtins.print'): choice_mock.return_value = 'y' KeeperApiHelper.communicate_expect( [pre_delete_command, 'delete']) cmd.execute(params, record=rec.record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect( [pre_delete_command, 'delete']) cmd.execute(params, record=rec.title) self.assertTrue(KeeperApiHelper.is_expect_empty()) choice_mock.return_value = 'n' KeeperApiHelper.communicate_expect([pre_delete_command]) cmd.execute(params, record=rec.record_uid) self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect([pre_delete_command]) cmd.execute(params, record=rec.title) self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_make_folder(self): params = get_synced_params() cmd = folder.FolderMakeCommand() def is_user_folder(rq): self.assertEqual(rq['command'], 'folder_add') self.assertEqual(rq['folder_type'], 'user_folder') def is_shared_folder(rq): self.assertEqual(rq['command'], 'folder_add') self.assertEqual(rq['folder_type'], 'shared_folder') def is_shared_folder_folder(rq): self.assertEqual(rq['command'], 'folder_add') self.assertEqual(rq['folder_type'], 'shared_folder_folder') KeeperApiHelper.communicate_expect([is_user_folder]) cmd.execute(params, user_folder=True, folder='New Folder') KeeperApiHelper.communicate_expect([is_shared_folder]) cmd.execute(params, shared_folder=True, folder='New Shared Folder') with mock.patch( 'keepercommander.commands.folder.user_choice') as mock_choice: mock_choice.return_value = 'n' KeeperApiHelper.communicate_expect([is_user_folder]) cmd.execute(params, folder='New Folder') self.assertTrue(KeeperApiHelper.is_expect_empty()) mock_choice.return_value = 'y' KeeperApiHelper.communicate_expect([is_shared_folder]) cmd.execute(params, folder='New Shared Folder') self.assertTrue(KeeperApiHelper.is_expect_empty()) with mock.patch('builtins.input') as mock_input: mock_choice.return_value = 'n' mock_input.return_value = 'New Personal Folder' KeeperApiHelper.communicate_expect([is_user_folder]) cmd.execute(params) self.assertTrue(KeeperApiHelper.is_expect_empty()) shared_folder = next( iter([ x for x in params.folder_cache.values() if x.type == 'shared_folder' ])) with self.assertLogs(level=logging.WARNING): cmd.execute(params, folder=shared_folder.name) params.current_folder = shared_folder.uid KeeperApiHelper.communicate_expect([is_shared_folder_folder]) cmd.execute(params, folder='New SubFolder') self.assertTrue(KeeperApiHelper.is_expect_empty())
def test_add_command(self): params = get_synced_params() cmd = recordv2.RecordAddCommand() with mock.patch('keepercommander.api.sync_down'): KeeperApiHelper.communicate_expect(['record_add']) cmd.execute(params, force=True, title='New Record') self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect(['record_add']) cmd.execute(params, login='******', password='******', url='url', custom='name1: value 1, name2: value 2', title='New Record') self.assertTrue(KeeperApiHelper.is_expect_empty()) KeeperApiHelper.communicate_expect(['record_add']) cmd.execute(params, login='******', password='******', url='url', custom=[{ 'name1': 'value 1', 'name2': 'value 2' }], title='New Record') self.assertTrue(KeeperApiHelper.is_expect_empty()) with mock.patch('builtins.input', return_value='Input Data'): KeeperApiHelper.communicate_expect(['record_add']) cmd.execute(params, force=True, title='New Record') self.assertTrue(KeeperApiHelper.is_expect_empty())