Skip to content

Commit a4d7a8b

Browse files
committed
Allow OAuth callback port override
1 parent 57ecccd commit a4d7a8b

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

awscli/customizations/sso/login.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ def _run_main(self, parsed_args, parsed_globals):
5757
session_name=sso_config.get('session_name'),
5858
registration_scopes=sso_config.get('registration_scopes'),
5959
use_device_code=parsed_args.use_device_code,
60+
redirect_address=(
61+
parsed_args.redirect_host,
62+
parsed_args.redirect_port,
63+
),
6064
)
6165
success_msg = 'Successfully logged into Start URL: %s\n'
6266
uni_print(success_msg % sso_config['sso_start_url'])

awscli/customizations/sso/utils.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,23 @@
6161
'instead of the Authorization Code flow.'
6262
),
6363
},
64+
{
65+
'name': 'redirect-host',
66+
'action': 'store',
67+
'default': '0.0.0.0',
68+
'help_text': (
69+
'Overrides OAuth callback address host instead of binding on all available local interfaces'
70+
),
71+
},
72+
{
73+
'name': 'redirect-port',
74+
'action': 'store',
75+
'cli_type_name': 'integer',
76+
'default': 0,
77+
'help_text': (
78+
'Overrides OAuth callback address port instead of arbitrary unused port'
79+
),
80+
},
6481
]
6582

6683

@@ -85,6 +102,7 @@ def do_sso_login(
85102
registration_scopes=None,
86103
session_name=None,
87104
use_device_code=False,
105+
redirect_address=None,
88106
):
89107
if token_cache is None:
90108
token_cache = JSONFileCache(SSO_TOKEN_DIR, dumps_func=_sso_json_dumps)
@@ -100,7 +118,7 @@ def do_sso_login(
100118
sso_region=sso_region,
101119
client_creator=session.create_client,
102120
parsed_globals=parsed_globals,
103-
auth_code_fetcher=AuthCodeFetcher(),
121+
auth_code_fetcher=AuthCodeFetcher(server_address=redirect_address),
104122
cache=token_cache,
105123
on_pending_authorization=on_pending_authorization,
106124
)
@@ -217,7 +235,7 @@ class AuthCodeFetcher:
217235
# How long we wait overall for the callback
218236
_OVERALL_TIMEOUT = 60 * 10
219237

220-
def __init__(self):
238+
def __init__(self, server_address=('0.0.0.0', 0)):
221239
self._auth_code = None
222240
self._state = None
223241
self._is_done = False
@@ -226,7 +244,7 @@ def __init__(self):
226244
# AuthCodeFetcher so that it can pass back the state and auth code
227245
try:
228246
handler = partial(OAuthCallbackHandler, self)
229-
self.http_server = HTTPServer(('', 0), handler)
247+
self.http_server = HTTPServer(server_address, handler)
230248
self.http_server.timeout = self._REQUEST_TIMEOUT
231249
except OSError as e:
232250
raise AuthCodeFetcherError(error_msg=e)

tests/functional/sso/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ def assert_device_browser_handler_called_with(
159159
verificationUriComplete, kwargs['verificationUriComplete']
160160
)
161161

162+
def assert_auth_code_fetcher_called_with(self, server_address):
163+
self.fetcher_mock.assert_called_once()
164+
_, kwargs = self.fetcher_mock.call_args
165+
self.assertEqual(server_address, kwargs["server_address"])
166+
162167
def assert_auth_browser_handler_called_with(self, expected_scopes):
163168
# The endpoint is subject to the endpoint rules, and the
164169
# code_challenge is not fixed so assert against the rest of the url

tests/functional/sso/test_login.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,17 @@ def test_login_device_sso_with_explicit_sso_session_arg(self):
332332
expected_token=self.access_token,
333333
)
334334

335+
def test_login_auth_sso_with_explicit_redirect_port(self):
336+
content = self.get_sso_session_config('test-session')
337+
self.set_config_file_content(content=content)
338+
self.add_oidc_auth_code_responses(self.access_token)
339+
self.run_cmd(
340+
'sso login --redirect-port 5050 --redirect-host 50.50.50.50'
341+
)
342+
self.assert_auth_code_fetcher_called_with(
343+
server_address=('50.50.50.50', 5050)
344+
)
345+
335346
def test_login_auth_sso_with_explicit_sso_session_arg(self):
336347
content = self.get_sso_session_config(
337348
'test-session', include_profile=False

0 commit comments

Comments
 (0)