Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix prefill_named_grant when set via GlobusApp #1075

Merged
merged 1 commit into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Fixed
~~~~~

- ``LoginFlowManager``\s built with ``GlobusApp`` now generate a more
appropriate value for ``prefill_named_grant``, using the current
hostname if possible. (:pr:`NUMBER`)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
OAuthTokenResponse,
)
from globus_sdk.gare import GlobusAuthorizationParameters
from globus_sdk.utils import get_nice_hostname

from .login_flow_manager import LoginFlowManager

Expand Down Expand Up @@ -74,11 +75,17 @@ def for_globus_app(
:raises GlobusSDKUsageError: if login_redirect_uri is not set on the config
but a ConfidentialAppAuthClient is supplied.
"""
hostname = get_nice_hostname()
if hostname:
prefill = f"{app_name} on {hostname}"
else:
prefill = app_name

return cls(
login_client,
redirect_uri=config.login_redirect_uri,
request_refresh_tokens=config.request_refresh_tokens,
native_prefill_named_grant=app_name,
native_prefill_named_grant=prefill,
)

def run_login_flow(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
)
from globus_sdk.gare import GlobusAuthorizationParameters
from globus_sdk.login_flows.login_flow_manager import LoginFlowManager
from globus_sdk.utils import get_nice_hostname

from .errors import LocalServerEnvironmentalLoginError, LocalServerLoginError
from .local_server import DEFAULT_HTML_TEMPLATE, RedirectHandler, RedirectHTTPServer
Expand Down Expand Up @@ -136,10 +137,16 @@ def for_globus_app(
msg = "LocalServerLoginFlowManager is only supported for Native Apps."
raise GlobusSDKUsageError(msg)

hostname = get_nice_hostname()
if hostname:
prefill = f"{app_name} on {hostname}"
else:
prefill = app_name

return cls(
login_client,
request_refresh_tokens=config.request_refresh_tokens,
native_prefill_named_grant=app_name,
native_prefill_named_grant=prefill,
)

def run_login_flow(
Expand Down
16 changes: 16 additions & 0 deletions src/globus_sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import collections.abc
import hashlib
import os
import platform
import sys
import typing as t
import uuid
Expand Down Expand Up @@ -70,6 +71,21 @@ def b64str(s: str) -> str:
return b64encode(s.encode("utf-8")).decode("utf-8")


def get_nice_hostname() -> str | None:
"""
Get the current hostname, with the following added behavior:

- if it ends in '.local', strip that suffix, as this is a frequent macOS behavior
'DereksCoolMacbook.local' -> 'DereksCoolMacbook'

- if the hostname is undiscoverable, return None
"""
name = platform.node()
if name.endswith(".local"):
return name[: -len(".local")]
return name or None


def slash_join(a: str, b: str | None) -> str:
"""
Join a and b with a single slash, regardless of whether they already
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,25 @@ def test_sha256string():
assert utils.sha256_string(test_string) == expected_sha


@pytest.mark.parametrize(
"platform_value, result",
(
# platform.node() can return '' when it doesn't know the hostname
# turn this into None
pytest.param("", None, id="empty-is-none"),
# macOS adds '.local' to the user's chosen machine name
pytest.param(
"VeryCoolMacbook.local", "VeryCoolMacbook", id="remove-local-suffix"
),
# the "boring" case is when we do no extra work
pytest.param("linux-workstation", "linux-workstation", id="boring"),
),
)
def test_get_nice_hostname(platform_value, result, monkeypatch):
monkeypatch.setattr("platform.node", lambda: platform_value)
assert utils.get_nice_hostname() == result


@pytest.mark.parametrize(
"a, b",
[(a, b) for a in ["a", "a/"] for b in ["b", "/b"]]
Expand Down
Loading