1818from awscli .customizations .sso .resolve import (
1919 _extract_region_from_hostname ,
2020 _follow_redirect ,
21+ _normalize_url ,
2122 is_aws_owned_domain ,
2223 resolve_start_url ,
2324)
@@ -87,19 +88,25 @@ def test_returns_none_for_region_less_hostnames(self, hostname):
8788 assert _extract_region_from_hostname (hostname ) is None
8889
8990
91+ class TestNormalizeUrl :
92+ @pytest .mark .parametrize (
93+ 'url, expected' ,
94+ [
95+ ('https://example.com:443/' , 'https://example.com' ),
96+ ('https://example.com:443/path/' , 'https://example.com/path' ),
97+ ('https://example.com/' , 'https://example.com' ),
98+ ('https://example.com:8443/path' , 'https://example.com:8443/path' ),
99+ ('http://example.com:80/' , 'http://example.com' ),
100+ ('https://example.com' , 'https://example.com' ),
101+ ],
102+ )
103+ def test_normalize_url (self , url , expected ):
104+ assert _normalize_url (url ) == expected
105+
106+
90107class TestResolveStartUrl :
91- def _mock_session (self , regions = None ):
92- if regions is None :
93- regions = [
94- 'us-east-1' ,
95- 'us-west-2' ,
96- 'eu-west-1' ,
97- 'us-gov-west-1' ,
98- 'cn-north-1' ,
99- ]
100- session = mock .Mock ()
101- session .get_available_regions .return_value = regions
102- return session
108+ def _mock_session (self ):
109+ return mock .Mock ()
103110
104111 def test_aws_owned_url_returns_configured_region (self ):
105112 session = self ._mock_session ()
@@ -139,6 +146,7 @@ def test_aws_owned_url_uses_configured_region_not_hostname(self):
139146 session = session ,
140147 configured_region = 'us-east-1' ,
141148 )
149+ assert resolved_url == 'https://ssoins-abc.portal.us-west-2.app.aws'
142150 assert region == 'us-east-1'
143151
144152 def test_awsapps_url_requires_configured_region (self ):
@@ -172,96 +180,39 @@ def test_invalid_url_raises_error(self):
172180 with pytest .raises (ConfigurationError , match = 'Invalid sso_start_url' ):
173181 resolve_start_url ('https://' , session = session )
174182
175- def test_vanity_url_invalid_region_raises_error (self ):
176- session = self ._mock_session (regions = ['us-east-1' , 'us-west-2' ])
177- with mock .patch (
178- 'awscli.customizations.sso.resolve._follow_redirect'
179- ) as mock_follow :
180- mock_follow .return_value = (
181- 'https://ssoins-abc.portal.fake-region-1.app.aws'
182- )
183- with pytest .raises (
184- ConfigurationError , match = 'not a known AWS region'
185- ):
186- resolve_start_url (
187- 'https://aws.mycompany.com' ,
188- session = session ,
189- )
183+ def test_vanity_url_follows_redirect (self ):
184+ session = self ._mock_session ()
185+ redirect_url = 'https://ssoins-abc.portal.us-east-1.app.aws:443/'
186+ normalized_url = 'https://ssoins-abc.portal.us-east-1.app.aws'
190187
191- def test_vanity_url_invalid_region_does_not_fall_back_to_configured (self ):
192- session = self ._mock_session (regions = ['us-east-1' , 'us-west-2' ])
193- with mock .patch (
194- 'awscli.customizations.sso.resolve._follow_redirect'
195- ) as mock_follow :
196- mock_follow .return_value = (
197- 'https://ssoins-abc.portal.fake-region-1.app.aws'
198- )
199- with pytest .raises (
200- ConfigurationError , match = 'not a known AWS region'
201- ):
202- resolve_start_url (
203- 'https://aws.mycompany.com' ,
204- session = session ,
205- configured_region = 'us-east-1' ,
206- )
207-
208- def test_vanity_url_govcloud_region_accepted (self ):
209- session = mock .Mock ()
210- session .get_available_regions .side_effect = (
211- lambda service , partition_name = 'aws' : {
212- 'aws' : ['us-east-1' , 'us-west-2' ],
213- 'aws-us-gov' : ['us-gov-west-1' ],
214- 'aws-cn' : ['cn-north-1' ],
215- }.get (partition_name , [])
216- )
217188 with mock .patch (
218189 'awscli.customizations.sso.resolve._follow_redirect'
219190 ) as mock_follow :
220- mock_follow .return_value = (
221- 'https://ssoins-abc.portal.us-gov-west-1.app.aws'
222- )
191+ mock_follow .return_value = redirect_url
223192 resolved_url , region = resolve_start_url (
224193 'https://aws.mycompany.com' ,
225194 session = session ,
226195 )
227- assert region == 'us-gov-west-1'
228-
229- def test_vanity_url_china_region_accepted (self ):
230- session = mock .Mock ()
231- session .get_available_regions .side_effect = (
232- lambda service , partition_name = 'aws' : {
233- 'aws' : ['us-east-1' , 'us-west-2' ],
234- 'aws-us-gov' : ['us-gov-west-1' ],
235- 'aws-cn' : ['cn-north-1' ],
236- }.get (partition_name , [])
237- )
238- with mock .patch (
239- 'awscli.customizations.sso.resolve._follow_redirect'
240- ) as mock_follow :
241- mock_follow .return_value = (
242- 'https://ssoins-abc.portal.cn-north-1.app.aws'
243- )
244- resolved_url , region = resolve_start_url (
245- 'https://aws.mycompany.com' ,
246- session = session ,
196+ assert resolved_url == normalized_url
197+ assert region == 'us-east-1'
198+ mock_follow .assert_called_once_with (
199+ 'https://aws.mycompany.com' , timeout = 10
247200 )
248- assert region == 'cn-north-1'
249201
250- def test_vanity_url_follows_redirect (self ):
202+ def test_vanity_url_uses_parsed_region_not_configured (self ):
251203 session = self ._mock_session ()
252- redirect_url = 'https://ssoins-abc.portal.us-east-1.app.aws:443/'
253-
254204 with mock .patch (
255205 'awscli.customizations.sso.resolve._follow_redirect'
256206 ) as mock_follow :
257- mock_follow .return_value = redirect_url
207+ mock_follow .return_value = (
208+ 'https://ssoins-abc.portal.us-west-2.app.aws'
209+ )
258210 resolved_url , region = resolve_start_url (
259211 'https://aws.mycompany.com' ,
260212 session = session ,
213+ configured_region = 'eu-west-1' ,
261214 )
262- assert resolved_url == redirect_url
263- assert region == 'us-east-1'
264- mock_follow .assert_called_once_with ('https://aws.mycompany.com' )
215+ assert region == 'us-west-2'
265216
266217 def test_vanity_url_resolves_to_non_aws_domain_raises_error (self ):
267218 session = self ._mock_session ()
@@ -283,6 +234,47 @@ def test_vanity_url_resolves_to_http_raises_error(self):
283234 with pytest .raises (ConfigurationError , match = 'must use https' ):
284235 resolve_start_url ('https://aws.mycompany.com' , session = session )
285236
237+ def test_vanity_url_region_less_requires_configured_region (self ):
238+ session = self ._mock_session ()
239+ with mock .patch (
240+ 'awscli.customizations.sso.resolve._follow_redirect'
241+ ) as mock_follow :
242+ mock_follow .return_value = 'https://d-abc123.awsapps.com/start'
243+ with pytest .raises (
244+ ConfigurationError , match = 'Cannot determine region'
245+ ):
246+ resolve_start_url ('https://aws.mycompany.com' , session = session )
247+
248+ def test_vanity_url_region_less_uses_configured_region (self ):
249+ session = self ._mock_session ()
250+ with mock .patch (
251+ 'awscli.customizations.sso.resolve._follow_redirect'
252+ ) as mock_follow :
253+ mock_follow .return_value = 'https://d-abc123.awsapps.com/start'
254+ resolved_url , region = resolve_start_url (
255+ 'https://aws.mycompany.com' ,
256+ session = session ,
257+ configured_region = 'us-east-1' ,
258+ )
259+ assert region == 'us-east-1'
260+
261+ def test_custom_timeout_passed_to_follow_redirect (self ):
262+ session = self ._mock_session ()
263+ with mock .patch (
264+ 'awscli.customizations.sso.resolve._follow_redirect'
265+ ) as mock_follow :
266+ mock_follow .return_value = (
267+ 'https://ssoins-abc.portal.us-east-1.app.aws'
268+ )
269+ resolve_start_url (
270+ 'https://aws.mycompany.com' ,
271+ session = session ,
272+ timeout = 5 ,
273+ )
274+ mock_follow .assert_called_once_with (
275+ 'https://aws.mycompany.com' , timeout = 5
276+ )
277+
286278
287279class TestFollowRedirect :
288280 def _make_http_error (self , code , headers = None ):
0 commit comments