diff --git a/funkwhale_cli/cli.py b/funkwhale_cli/cli.py index 12bc25f09459f519405cfcfb96526a9e8560e770..fa892e39452385d8c852b857925d93a4a7ad6fb2 100644 --- a/funkwhale_cli/cli.py +++ b/funkwhale_cli/cli.py @@ -88,6 +88,35 @@ RAW_DECORATOR = click.option( "--raw", is_flag=True, help="Directly output JSON returned by the happy" ) +class lazy_credential(): + """ + A proxy object to request access to the proxy object at the later possible point, + cf #4 + """ + def __init__(self, *args): + self.args = args + self._cached_value = None + + @property + def value(self): + if self._cached_value: + return self._cached_value + v = keyring.get_password(*self.args) + self._cached_value = v + return v + + def __str__(self): + return str(self.value) + + def __eq__(self, other): + return self.value == other + + def __repr__(self): + return str(self.value) + + def __bool__(self): + return bool(self.value) + def set_server(ctx, url, token): ctx.ensure_object(dict) @@ -96,7 +125,7 @@ def set_server(ctx, url, token): ctx.obj["SERVER_NETLOC"] = parsed.netloc ctx.obj["SERVER_PROTOCOL"] = parsed.scheme try: - token = token or keyring.get_password(url, "_") + token = token or lazy_credential(url, "_") except ValueError as e: raise click.ClickException("Error while retrieving password from keyring: {}. Your password may be incorrect.".format(e.args[0])) except Exception as e: diff --git a/tests/test_cli.py b/tests/test_cli.py index 4697133d04ea6fde038f95f64fc87c991edcf035..5ba5983e60299ae160843daab6884208a5fb1c69 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,5 +1,6 @@ import pytest import click +import keyring from funkwhale_cli import api from funkwhale_cli import cli @@ -61,3 +62,20 @@ def test_delete_command(group, cli_ctx, session, responses): ) def test_get_pagination_data(input, output): assert cli.get_pagination_data(input) == output + + +def test_lazy_credential(mocker): + get_password = mocker.patch("keyring.get_password", return_value="password") + credential = cli.lazy_credential("http://testurl", "_") + + get_password.assert_not_called() + + str(credential) + + get_password.assert_called_once_with("http://testurl", "_") + + assert credential == "password" + + # result is cached + str(credential) + assert get_password.call_count == 1