예제 #1
0
def test_env_var_provider_configure_encrypted_value():
    def check_env_var_provider_config_local_state(dirname):
        provider = EnvVarProvider()
        requirement = _load_env_var_requirement(dirname, "FOO_PASSWORD")
        assert requirement.encrypted
        local_state_file = LocalStateFile.load_for_directory(dirname)
        status = requirement.check_status(dict(), local_state_file, 'default',
                                          UserConfigOverrides())
        assert dict(source='unset') == status.analysis.config

        assert local_state_file.get_value(['variables', 'FOO_PASSWORD'
                                           ]) is None
        assert set(keyring.fallback_data().values()) == set()

        environ = dict(CONDA_DEFAULT_ENV='/pretend/env',
                       CONDA_ENV_PATH='/pretend/env',
                       CONDA_PREFIX='/pretend/env')

        provider.set_config_values_as_strings(requirement, environ,
                                              local_state_file, 'default',
                                              UserConfigOverrides(),
                                              dict(value="bar"))

        # should not have affected local state, should use keyring
        assert local_state_file.get_value(['variables', 'FOO_PASSWORD'
                                           ]) is None
        assert set(keyring.fallback_data().values()) == set(["bar"])

        # setting empty string = unset
        provider.set_config_values_as_strings(requirement, environ,
                                              local_state_file, 'default',
                                              UserConfigOverrides(),
                                              dict(value=""))
        assert local_state_file.get_value(['variables', 'FOO_PASSWORD'
                                           ]) is None
        assert set(keyring.fallback_data().values()) == set()

    keyring.enable_fallback_keyring()
    try:
        with_directory_contents_completing_project_file(
            {DEFAULT_PROJECT_FILENAME: """
variables:
  - FOO_PASSWORD
"""}, check_env_var_provider_config_local_state)
    finally:
        keyring.disable_fallback_keyring()
예제 #2
0
def test_ask_variables_interactively(monkeypatch):
    def check(dirname):
        project_dir_disable_dedicated_env(dirname)

        def mock_is_interactive():
            return True

        monkeypatch.setattr(
            'anaconda_project.internal.cli.console_utils.stdin_is_interactive',
            mock_is_interactive)

        inputs = ["foo", "bar"]

        def mock_console_input(prompt, encrypted):
            return inputs.pop(0)

        monkeypatch.setattr(
            'anaconda_project.internal.cli.console_utils.console_input',
            mock_console_input)

        res = _parse_args_and_run_subcommand(
            ['anaconda-project', 'prepare', '--directory', dirname])
        assert res == 0

        local_state = LocalStateFile.load_for_directory(dirname)
        assert local_state.get_value(['variables', 'FOO']) == 'foo'
        assert local_state.get_value(['variables', 'BAR_PASSWORD']) is None
        assert set(keyring.fallback_data().values()) == set(['bar'])

    keyring.enable_fallback_keyring()
    try:
        with_directory_contents_completing_project_file(
            {
                DEFAULT_PROJECT_FILENAME:
                """
variables:
  FOO: null
  BAR_PASSWORD: null
"""
            }, check)
    finally:
        keyring.disable_fallback_keyring()
예제 #3
0
def test_prepare_asking_for_password_with_browser(monkeypatch):
    keyring.reset_keyring_module()

    # In this scenario, we store a password in the keyring.
    from tornado.ioloop import IOLoop
    io_loop = IOLoop()

    http_results = {}

    def click_submit(url):
        from anaconda_project.internal.test.http_utils import http_get_async, http_post_async
        from tornado import gen

        @gen.coroutine
        def do_http():
            http_results['get_click_submit'] = get_response = yield http_get_async(url)

            if get_response.code != 200:
                raise Exception("got a bad http response " + repr(get_response))

            http_results['post_click_submit'] = post_response = yield http_post_async(url, body="")

            assert 200 == post_response.code
            assert '</form>' in str(post_response.body)
            assert 'FOO_PASSWORD' in str(post_response.body)

            fill_in_password(url, post_response)

        io_loop.add_callback(do_http)

    def fill_in_password(url, first_response):
        from anaconda_project.internal.test.http_utils import http_post_async
        from anaconda_project.internal.plugin_html import _BEAUTIFUL_SOUP_BACKEND
        from tornado import gen
        from bs4 import BeautifulSoup

        if first_response.code != 200:
            raise Exception("got a bad http response " + repr(first_response))

        # set the FOO_PASSWORD field
        soup = BeautifulSoup(first_response.body, _BEAUTIFUL_SOUP_BACKEND)
        password_fields = soup.find_all("input", attrs={'type': 'password'})
        if len(password_fields) == 0:
            print("No password fields in " + repr(soup))
            raise Exception("password field not found")
        else:
            field = password_fields[0]

        assert 'name' in field.attrs

        @gen.coroutine
        def do_http():
            http_results['post_fill_in_password'] = yield http_post_async(url, form={field['name']: 'bloop'})

        io_loop.add_callback(do_http)

    def mock_open_new_tab(url):
        return click_submit(url)

    monkeypatch.setattr('webbrowser.open_new_tab', mock_open_new_tab)

    def prepare_with_browser(dirname):
        project = project_no_dedicated_env(dirname)
        environ = minimal_environ()
        result = prepare_with_browser_ui(project, environ=environ, keep_going_until_success=False, io_loop=io_loop)
        assert result.errors == []
        assert result
        assert dict(FOO_PASSWORD='******', PROJECT_DIR=project.directory_path) == strip_environ(result.environ)
        assert dict() == strip_environ(environ)

        # wait for the results of the POST to come back,
        # awesome hack-tacular
        while 'post_fill_in_password' not in http_results:
            io_loop.call_later(0.01, lambda: io_loop.stop())
            io_loop.start()

        assert 'get_click_submit' in http_results
        assert 'post_click_submit' in http_results
        assert 'post_fill_in_password' in http_results

        assert 200 == http_results['get_click_submit'].code
        assert 200 == http_results['post_click_submit'].code
        assert 200 == http_results['post_fill_in_password'].code

        final_done_html = str(http_results['post_fill_in_password'].body)
        assert "Done!" in final_done_html
        assert "Environment variable FOO_PASSWORD is set." in final_done_html

        local_state_file = LocalStateFile.load_for_directory(project.directory_path)
        assert local_state_file.get_value(['variables', 'FOO_PASSWORD']) is None

        # now a no-browser prepare() should read password from the
        # keyring

    keyring.enable_fallback_keyring()
    try:
        with_directory_contents_completing_project_file(
            {DEFAULT_PROJECT_FILENAME: """
variables:
  FOO_PASSWORD: {}
"""}, prepare_with_browser)
    finally:
        keyring.disable_fallback_keyring()
def _with_fallback_keyring(f):
    try:
        keyring.enable_fallback_keyring()
        f()
    finally:
        keyring.disable_fallback_keyring()