Skip to content

Commit

Permalink
Unquote scope strings when seen with single quotes (#778)
Browse files Browse the repository at this point in the history
* Unquote scope strings when seen with single quotes

This change originates with a bug report about
`globus session consent` on Windows Command Prompt. The single quote
chars are not interpreted by the shell, so we receive them verbatim.

After discussing the tradeoffs between this fix and switching to
double-quotes for the scope string emission piece, choose this one.
The impact is small and easy to test in unit tests.

Fun fact: there's also an "easy" bypass mechanism on modern shells
if anyone needs to pass leading and trailing single quotes in the
future. Just pass an extra (literal) leading and trailing quote.

Because there is no suite of functional tests for
`globus session consent` today, none is added here.

* Fix mypy failure due to list invariance
  • Loading branch information
sirosen authored Mar 14, 2023
1 parent 3ef1088 commit 1d6da55
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
4 changes: 4 additions & 0 deletions changelog.d/20230314_120621_sirosen_cmdprompt_quoting_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Bugfixes

* Strip single quotes from scope strings passed to `globus session consent`,
fixing the behavior of this command when run from Windows Command Prompt
8 changes: 7 additions & 1 deletion src/globus_cli/commands/session/consent.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from __future__ import annotations

import click
from globus_sdk.scopes import MutableScope

from globus_cli import utils
from globus_cli.login_manager import LoginManager
from globus_cli.parsing import command, no_local_server_option

Expand All @@ -21,7 +23,11 @@ def session_consent(scopes: tuple[str], no_local_server: bool) -> None:
This command is necessary when the CLI needs access to resources which require the
user to explicitly consent to access.
"""
scope_list: list[str | MutableScope] = [
utils.unquote_cmdprompt_single_quotes(s) for s in scopes
]
manager = LoginManager()

manager.run_login_flow(
no_local_server=no_local_server,
local_server_message=(
Expand All @@ -33,5 +39,5 @@ def session_consent(scopes: tuple[str], no_local_server: bool) -> None:
"\n---"
),
epilog="\nYou have successfully updated your CLI session.\n",
scopes=list(scopes),
scopes=scope_list,
)
18 changes: 18 additions & 0 deletions src/globus_cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@
F = t.TypeVar("F", bound=t.Callable)


def unquote_cmdprompt_single_quotes(arg: str) -> str:
"""
remove leading and trailing single quotes from a string when
there is a leading and trailing single quote
per the name of this function, it is meant to provide compatibility
with cmdprompt which interprets inputs like
$ mycmd 'foo'
as including the single quote chars and passes "'foo'" to our
commands
"""
if len(arg) >= 2 and arg[0] == "'" and arg[-1] == "'":
return arg[1:-1]
return arg


def fold_decorators(f: F, decorators: list[t.Callable[[F], F]]) -> F:
for deco in decorators:
f = deco(f)
Expand Down
24 changes: 23 additions & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
from globus_cli.utils import format_list_of_words, format_plural_str
import pytest

from globus_cli.utils import (
format_list_of_words,
format_plural_str,
unquote_cmdprompt_single_quotes,
)


def test_format_word_list():
Expand All @@ -16,3 +22,19 @@ def test_format_plural_str():
wordforms = {"this": "these", "command": "commands"}
assert format_plural_str(fmt, wordforms, True) == "you need to run these commands"
assert format_plural_str(fmt, wordforms, False) == "you need to run this command"


@pytest.mark.parametrize(
"arg, expect",
(
("foo", "foo"),
("'foo'", "foo"),
("'", "'"),
("'foo", "'foo"),
("foo'", "foo'"),
("''", ""),
('"foo"', '"foo"'),
),
)
def test_unquote_cmdprompt_squote(arg, expect):
assert unquote_cmdprompt_single_quotes(arg) == expect

0 comments on commit 1d6da55

Please sign in to comment.