Skip to content

Commit 82c54e4

Browse files
committed
accept true/false for ssl_mode, keeping on/off
More liberally accept true/false/on/off (and capitalization variants) for --ssl_mode. Some inconsistencies in the interface have crept in as features were added. Some settings from ~/.myclirc especially, but also in the CLI arguments, use str_to_bool() for liberal boolean parsing. Other settings, such as --ssl_mode, are using on/off only. Other settings, such as --use_keyring, are using true/false only. This change is a step towards converging all boolean settings on liberal str_to_bool(). It should ultimately include DSN query parameters, too. The "auto" value for ssl_mode is still special-cased, and not affected by these changes. The only loss is that click doesn't automatically display the choices in the helpdoc, but they are already listed in the description. We keep the description targeted to on/off, and only silently accept the other variants.
1 parent 19a7bfc commit 82c54e4

File tree

5 files changed

+71
-3
lines changed

5 files changed

+71
-3
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Features
66
* Let the `--dsn` argument accept literal DSNs as well as aliases.
77
* Accept `--character-set` as an alias for `--charset` at the CLI.
88
* Add SSL/TLS version to `status` output.
9+
* More liberally accept `on`/`off` values for `true`/`false`, and vice versa.
910

1011

1112
Bug Fixes

mycli/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,13 @@ def str_to_bool(s: str | bool) -> bool:
305305
raise ValueError(f'not a recognized boolean value: {s}')
306306

307307

308+
def str_to_on_off(s: str | bool) -> str:
309+
bool_str = str(str_to_bool(s))
310+
if bool_str == 'True':
311+
return 'on'
312+
return 'off'
313+
314+
308315
def strip_matching_quotes(s: str) -> str:
309316
"""Remove matching, surrounding quotes from a string.
310317

mycli/main.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,15 @@
5656
from mycli.clitoolbar import create_toolbar_tokens_func
5757
from mycli.compat import WIN
5858
from mycli.completion_refresher import CompletionRefresher
59-
from mycli.config import get_mylogin_cnf_path, open_mylogin_cnf, read_config_files, str_to_bool, strip_matching_quotes, write_default_config
59+
from mycli.config import (
60+
get_mylogin_cnf_path,
61+
open_mylogin_cnf,
62+
read_config_files,
63+
str_to_bool,
64+
str_to_on_off,
65+
strip_matching_quotes,
66+
write_default_config,
67+
)
6068
from mycli.key_bindings import mycli_bindings
6169
from mycli.lexer import MyCliLexer
6270
from mycli.packages import special
@@ -220,7 +228,9 @@ def __init__(
220228

221229
# set ssl_mode if a valid option is provided in a config file, otherwise None
222230
ssl_mode = c["main"].get("ssl_mode", None) or c["connection"].get("default_ssl_mode", None)
223-
if ssl_mode not in ("auto", "on", "off", None):
231+
if ssl_mode is None:
232+
pass
233+
elif ssl_mode.lower() not in ("auto", "on", "off", "1", "0", "true", "false"):
224234
self.echo(f"Invalid config option provided for ssl_mode ({ssl_mode}); ignoring.", err=True, fg="red")
225235
self.ssl_mode = None
226236
else:
@@ -1659,7 +1669,7 @@ def get_last_query(self) -> str | None:
16591669
"--ssl-mode",
16601670
"ssl_mode",
16611671
help="Set desired SSL behavior. auto=preferred, on=required, off=off.",
1662-
type=click.Choice(["auto", "on", "off"]),
1672+
type=str,
16631673
)
16641674
@click.option("--ssl/--no-ssl", "ssl_enable", default=None, help="Enable SSL for connection (automatically enabled with other flags).")
16651675
@click.option("--ssl-ca", help="CA file in PEM format.", type=click.Path(exists=True))
@@ -1995,6 +2005,14 @@ def get_password_from_file(password_file: str | None) -> str | None:
19952005
ssl_enable = True
19962006

19972007
ssl_mode = ssl_mode or mycli.ssl_mode # cli option or config option
2008+
if ssl_mode:
2009+
ssl_mode = ssl_mode.lower()
2010+
if ssl_mode and ssl_mode != 'auto':
2011+
try:
2012+
ssl_mode = str_to_on_off(ssl_mode)
2013+
except ValueError:
2014+
click.secho('Unknown value for ssl_mode', err=True, fg='red')
2015+
sys.exit(1)
19982016

19992017
# if there is a mismatch between the ssl_mode value and other sources of ssl config, show a warning
20002018
# specifically using "is False" to not pickup the case where ssl_enable is None (not set by the user)

test/test_config.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
read_and_decrypt_mylogin_cnf,
1717
read_config_file,
1818
str_to_bool,
19+
str_to_on_off,
1920
strip_matching_quotes,
2021
)
2122

@@ -149,6 +150,25 @@ def test_str_to_bool():
149150
str_to_bool(None)
150151

151152

153+
def test_str_to_on_off():
154+
assert str_to_on_off(False) == 'off'
155+
assert str_to_on_off(True) == 'on'
156+
assert str_to_on_off("False") == 'off'
157+
assert str_to_on_off("True") == 'on'
158+
assert str_to_on_off("TRUE") == 'on'
159+
assert str_to_on_off("1") == 'on'
160+
assert str_to_on_off("0") == 'off'
161+
assert str_to_on_off("on") == 'on'
162+
assert str_to_on_off("off") == 'off'
163+
assert str_to_on_off("off") == 'off'
164+
165+
with pytest.raises(ValueError):
166+
str_to_on_off("foo")
167+
168+
with pytest.raises(TypeError):
169+
str_to_on_off(None)
170+
171+
152172
def test_read_config_file_list_values_default():
153173
"""Test that reading a config file uses list_values by default."""
154174

test/test_main.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,17 @@ def test_ssl_mode_on(executor, capsys):
154154
assert ssl_cipher
155155

156156

157+
@dbtest
158+
def test_ssl_mode_true(executor, capsys):
159+
runner = CliRunner()
160+
ssl_mode = 'true'
161+
sql = 'select * from performance_schema.session_status where variable_name = "Ssl_cipher"'
162+
result = runner.invoke(cli, args=CLI_ARGS + ['--csv', '--ssl-mode', ssl_mode], input=sql)
163+
result_dict = next(csv.DictReader(result.stdout.split('\n')))
164+
ssl_cipher = result_dict.get('VARIABLE_VALUE', None)
165+
assert ssl_cipher
166+
167+
157168
@dbtest
158169
def test_ssl_mode_auto(executor, capsys):
159170
runner = CliRunner()
@@ -176,6 +187,17 @@ def test_ssl_mode_off(executor, capsys):
176187
assert not ssl_cipher
177188

178189

190+
@dbtest
191+
def test_ssl_mode_false(executor, capsys):
192+
runner = CliRunner()
193+
ssl_mode = 'False'
194+
sql = 'select * from performance_schema.session_status where variable_name = "Ssl_cipher"'
195+
result = runner.invoke(cli, args=CLI_ARGS + ['--csv', '--ssl-mode', ssl_mode], input=sql)
196+
result_dict = next(csv.DictReader(result.stdout.split('\n')))
197+
ssl_cipher = result_dict.get('VARIABLE_VALUE', None)
198+
assert not ssl_cipher
199+
200+
179201
@dbtest
180202
def test_ssl_mode_overrides_ssl(executor, capsys):
181203
runner = CliRunner()

0 commit comments

Comments
 (0)