Exemple #1
0
    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_search_command(self):
        params = get_synced_params()
        cmd = record.SearchCommand()

        with mock.patch('builtins.print'):
            cmd.execute(params, pattern='.*')
            cmd.execute(params, pattern='Non-existing-name')
    def test_share_record(self):
        params = get_synced_params()

        record_uid = next(
            iter([
                x['record_uid'] for x in params.meta_data_cache.values()
                if x['can_share']
            ]))
        cmd = register.ShareRecordCommand()

        TestRegister.expected_commands.extend(['record_share_update'])
        cmd.execute(params,
                    email=['*****@*****.**'],
                    action='grant',
                    can_share=False,
                    can_edit=True,
                    record=record_uid)
        self.assertEqual(len(TestRegister.expected_commands), 0)

        TestRegister.expected_commands.extend(['record_share_update'])
        cmd.execute(params,
                    email=['*****@*****.**'],
                    action='owner',
                    can_share=False,
                    can_edit=True,
                    record=record_uid)
        self.assertEqual(len(TestRegister.expected_commands), 0)

        TestRegister.expected_commands.extend(['record_share_update'])
        cmd.execute(params,
                    email=['*****@*****.**'],
                    action='revoke',
                    record=record_uid)
        self.assertEqual(len(TestRegister.expected_commands), 0)
    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_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())
Exemple #6
0
    def test_export_import(self):
        params_export = get_synced_params()
        cmd_export = commands.RecordExportCommand()
        param_import = get_connected_params()
        cmd_import = commands.RecordImportCommand()

        json_text = ''

        def mock_write(text):
            nonlocal json_text
            json_text += text

        def mock_read():
            nonlocal json_text
            return json_text

        with mock.patch('keepercommander.api.sync_down'), mock.patch('builtins.open', mock.mock_open()) as m_open:
            m_open.return_value.write = mock_write
            cmd_export.execute(params_export, format='json', name='json')

        with mock.patch('keepercommander.api.sync_down'), mock.patch('builtins.open', mock.mock_open()) as m_open:
            m_open.return_value.read = mock_read
            self.communicate_mock.side_effect = None
            self.communicate_mock.return_value = {
                'result': 'success',
                'result_code': '',
                'message': ''
            }
            with mock.patch('os.path.isfile', return_value=True):
                cmd_import.execute(param_import, format='json', name='json')
Exemple #7
0
    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())
Exemple #8
0
    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])
Exemple #9
0
    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_list(self):
        params = get_synced_params()

        cmd = folder.FolderListCommand()
        with mock.patch('builtins.print'), mock.patch('keepercommander.api.get_record_shares'):
            cmd.execute(params)
            cmd.execute(params, detail=True)
Exemple #11
0
    def test_get_shared_folder_uid(self):
        params = get_synced_params()
        cmd = record.RecordGetUidCommand()

        shared_folder_uid = next(iter(params.shared_folder_cache))
        with mock.patch('builtins.print'):
            cmd.execute(params, uid=shared_folder_uid)
            cmd.execute(params, format='json', uid=shared_folder_uid)
Exemple #12
0
    def test_tree(self):
        params = get_synced_params()
        cmd = folder.FolderTreeCommand()

        with mock.patch('builtins.print'):
            cmd.execute(params)
        with self.assertRaises(CommandError):
            cmd.execute(params, folder='Invalid')
    def test_change_directory(self):
        params = get_synced_params()

        cmd = folder.FolderCdCommand()
        folder_name = next(iter([x['name_unencrypted'] for x in params.shared_folder_cache.values()]))
        owd = params.current_folder
        cmd.execute(params, folder=folder_name)
        self.assertNotEqual(owd, params.current_folder)
    def test_get_team_uid(self):
        params = get_synced_params()
        cmd = recordv2.RecordGetUidCommand()

        team_uid = next(iter(params.team_cache))
        with mock.patch('builtins.print'):
            cmd.execute(params, uid=team_uid)
            cmd.execute(params, format='json', uid=team_uid)
    def test_get_record_uid(self):
        params = get_synced_params()
        cmd = recordv2.RecordGetUidCommand()

        record_uid = next(iter(params.subfolder_record_cache['']))
        with mock.patch('builtins.print'), mock.patch(
                'keepercommander.api.get_record_shares'):
            cmd.execute(params, uid=record_uid)
            cmd.execute(params, format='json', uid=record_uid)
    def test_shared_list_command(self):
        params = get_synced_params()
        cmd = record.RecordListSfCommand()

        with mock.patch('builtins.print') as mock_print:
            cmd.execute(params, pattern='folder')
            mock_print.assert_called()

            mock_print.reset_mock()
            cmd.execute(params, pattern='INVALID')
            mock_print.assert_not_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())
Exemple #18
0
    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_share_folder(self):
        params = get_synced_params()
        shared_folder_uid = next(iter([x['shared_folder_uid'] for x in params.shared_folder_cache.values()]))
        cmd = register.ShareFolderCommand()

        TestRegister.expected_commands.extend(['shared_folder_update'])
        cmd.execute(params, action='grant', user=['*****@*****.**'], manage_records=True, manage_users=False, folder=shared_folder_uid)
        self.assertEqual(len(TestRegister.expected_commands), 0)

        TestRegister.expected_commands.extend(['shared_folder_update'])
        cmd.execute(params, action='revoke', user=['*****@*****.**'], folder=shared_folder_uid)
        self.assertEqual(len(TestRegister.expected_commands), 0)
    def test_append_notes_command(self):
        params = get_synced_params()
        cmd = recordv2.RecordAppendNotesCommand()

        record_uid = next(iter(params.subfolder_record_cache['']))
        with mock.patch('keepercommander.api.update_record'):
            cmd.execute(params, notes='notes', record=record_uid)

            with mock.patch('builtins.input', return_value='data'):
                cmd.execute(params, record=record_uid)

        with self.assertRaises(CommandError):
            cmd.execute(params, notes='notes', record='invalid')
    def test_move_invalid_input(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['']))

        with self.assertRaises(CommandError):
            cmd.execute(params, src='Invalid Record', dst=user_folder.uid)
            cmd.execute(params, src=root_record_uid, dst='Invalid Folder')
            cmd.execute(params, src=user_folder.uid, dst=user_folder.uid)
    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())
Exemple #23
0
    def test_search_records(self):
        params = get_synced_params()

        records = api.search_records(params, '')
        self.assertEqual(len(records), len(params.record_cache))

        records = api.search_records(params, 'RECORD')
        self.assertEqual(len(records), len(params.record_cache))

        records = api.search_records(params, 'Record 1')
        self.assertEqual(len(records), 1)

        records = api.search_records(params, 'INVALID')
        self.assertEqual(len(records), 0)
Exemple #24
0
    def test_search_shared_folders(self):
        params = get_synced_params()

        sfs = api.search_shared_folders(params, '')
        self.assertEqual(len(sfs), len(params.shared_folder_cache))

        sfs = api.search_shared_folders(params, 'folder')
        self.assertEqual(len(sfs), len(params.shared_folder_cache))

        sfs = api.search_shared_folders(params, '1')
        self.assertEqual(len(sfs), 1)

        sfs = api.search_shared_folders(params, 'INVALID')
        self.assertEqual(len(sfs), 0)
Exemple #25
0
    def test_search_teams(self):
        params = get_synced_params()

        teams = api.search_teams(params, '')
        self.assertEqual(len(teams), len(params.team_cache))

        teams = api.search_shared_folders(params, 'team')
        self.assertEqual(len(teams), len(params.shared_folder_cache))

        teams = api.search_shared_folders(params, '1')
        self.assertEqual(len(teams), 1)

        teams = api.search_shared_folders(params, 'INVALID')
        self.assertEqual(len(teams), 0)
    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())
Exemple #27
0
    def test_record_list_command(self):
        params = get_synced_params()
        cmd = record.RecordListCommand()

        with mock.patch('builtins.print') as mock_print, mock.patch(
                'keepercommander.api.get_record_shares') as mock_shares:
            cmd.execute(params, pattern='record')
            mock_print.assert_called()
            mock_shares.assert_called()

            mock_print.reset_mock()
            mock_shares.reset_mock()
            cmd.execute(params, pattern='INVALID')
            mock_print.assert_not_called()
            mock_shares.assert_not_called()
    def test_download_attachment_command(self):
        params = get_synced_params()
        cmd = recordv2.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 = {
        }  # type: dict[any, tuple[attachment.AttachmentDownloadRequest, bytes]]
        for file in extra['files']:
            atta_id = file['id']  # type: str
            key = utils.base64_url_decode(file['key'])
            body_encoded = crypto.encrypt_aes_v1(os.urandom(file['size']), key)
            rq = attachment.AttachmentDownloadRequest()
            rq.title = 'Title'
            rq.url = f'https://keepersecurity.com/files/{atta_id}'
            rq.is_gcm_encrypted = False
            rq.encryption_key = key

            attachments[atta_id] = (rq, body_encoded)

        def prepare_download(params, record_uid):
            return (x[0] for x in attachments.values())

        def requests_get(url, **kwargs):
            body = next(
                (x[1] for x in attachments.values() if x[0].url == url), None)
            if not body:
                raise Exception(f'URL \"{url}\" not found.')
            rs = mock.Mock()
            rs.status_code = 200
            stream = io.BytesIO(body)
            rs.raw = stream
            rs.__enter__ = mock.Mock(return_value=rs)
            rs.__exit__ = mock.Mock(return_value=None)
            return rs

        with mock.patch('keepercommander.attachment.prepare_attachment_download', side_effect=prepare_download), \
                mock.patch('requests.get', side_effect=requests_get), \
                mock.patch('builtins.open', mock.mock_open()), \
                mock.patch('os.path.abspath', return_value='/file_name'):
            cmd.execute(params, record=record_uid)
Exemple #29
0
    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())
Exemple #30
0
    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)