Skip to content

Commit afd833a

Browse files
authored
{AuthV2} az webapp auth update: Fix --excluded-paths logic (#9315)
* az webapp auth update --excluded-path silently truncates or misparses path value Fixes #31803 * linting * added fix for authV2 parsing with testing, rerecorded all cassettes * fixed testing * updated tests * updated tests location for sku
1 parent 1867801 commit afd833a

File tree

8 files changed

+4393
-990
lines changed

8 files changed

+4393
-990
lines changed

src/authV2/HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
Release History
44
===============
55

6+
1.0.1
7+
++++++
8+
* Fix excluded paths parsing in `az webapp auth update` command.
9+
610
1.0.0
711
++++++
812
* Update module documentation.

src/authV2/azext_authV2/custom.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,16 @@ def update_auth_settings_v2(cmd, resource_group_name, name, set_string=None, ena
159159
if excluded_paths is not None:
160160
if "globalValidation" not in existing_auth.keys():
161161
existing_auth["globalValidation"] = {}
162-
excluded_paths_list_string = excluded_paths[1:-1]
163-
existing_auth["globalValidation"]["excludedPaths"] = excluded_paths_list_string.split(",")
162+
try:
163+
parsed = json.loads(excluded_paths)
164+
if isinstance(parsed, list):
165+
excluded_paths_list = parsed
166+
else:
167+
excluded_paths_list = [parsed] if parsed else []
168+
except json.JSONDecodeError:
169+
excluded_paths_list = excluded_paths.split(",")
170+
171+
existing_auth["globalValidation"]["excludedPaths"] = excluded_paths_list
164172

165173
existing_auth = update_http_settings_in_auth_settings(existing_auth, require_https,
166174
proxy_convention, proxy_custom_host_header,

src/authV2/azext_authV2/tests/latest/recordings/test_authV2_auth.yaml

Lines changed: 799 additions & 339 deletions
Large diffs are not rendered by default.

src/authV2/azext_authV2/tests/latest/recordings/test_authV2_authclassic.yaml

Lines changed: 345 additions & 302 deletions
Large diffs are not rendered by default.

src/authV2/azext_authV2/tests/latest/recordings/test_authV2_clientsecret_param_combinations.yaml

Lines changed: 804 additions & 339 deletions
Large diffs are not rendered by default.

src/authV2/azext_authV2/tests/latest/recordings/test_authV2_excluded_paths_parsing.yaml

Lines changed: 2361 additions & 0 deletions
Large diffs are not rendered by default.

src/authV2/azext_authV2/tests/latest/test_authV2_scenario.py

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
class Authv2ScenarioTest(ScenarioTest):
1717

1818
@ResourceGroupPreparer(name_prefix='cli_test_authV2')
19+
@AllowLargeResponse()
1920
def test_authV2_clientsecret_param_combinations(self, resource_group):
2021
webapp_name = self.create_random_name('webapp-authentication-test', 40)
2122
plan_name = self.create_random_name('webapp-authentication-plan', 40)
2223
self.cmd(
23-
'appservice plan create -g {} -n {} --sku S1'.format(resource_group, plan_name))
24+
'appservice plan create -g {} -n {} --sku S1 --location westus2'.format(resource_group, plan_name))
2425
self.cmd(
2526
'webapp create -g {} -n {} --plan {}'.format(resource_group, webapp_name, plan_name))
2627
self.cmd('webapp auth config-version show -g {} -n {}'.format(resource_group, webapp_name)).assert_with_checks([
@@ -29,13 +30,15 @@ def test_authV2_clientsecret_param_combinations(self, resource_group):
2930

3031
# testing show command for newly created app and initial fields
3132
self.cmd('webapp auth show -g {} -n {}'.format(resource_group, webapp_name)).assert_with_checks([
32-
JMESPathCheck('properties', {})
33+
JMESPathCheck('properties.platform.enabled', False)
3334
])
35+
self.cmd('webapp auth config-version upgrade -g {} -n {}'.format(resource_group, webapp_name))
3436

3537
# # update and verify
3638
self.cmd('webapp auth update -g {} -n {} --enabled true --runtime-version 1.2.8'
3739
.format(resource_group, webapp_name)).assert_with_checks([
38-
JMESPathCheck('platform', "{'enabled': True, 'runtimeVersion': '1.2.8'}")
40+
JMESPathCheck('platform.enabled', True),
41+
JMESPathCheck('platform.runtimeVersion', '1.2.8')
3942
])
4043

4144
with self.assertRaisesRegex(ArgumentUsageError, 'Usage Error: --client-secret and --client-secret-setting-name cannot both be '
@@ -79,11 +82,12 @@ def test_authV2_clientsecret_param_combinations(self, resource_group):
7982
.format(resource_group, webapp_name))
8083

8184
@ResourceGroupPreparer(name_prefix='cli_test_authV2')
85+
@AllowLargeResponse()
8286
def test_authV2_auth(self, resource_group):
8387
webapp_name = self.create_random_name('webapp-authentication-test', 40)
8488
plan_name = self.create_random_name('webapp-authentication-plan', 40)
8589
self.cmd(
86-
'appservice plan create -g {} -n {} --sku S1'.format(resource_group, plan_name))
90+
'appservice plan create -g {} -n {} --sku S1 --location westus2'.format(resource_group, plan_name))
8791
self.cmd(
8892
'webapp create -g {} -n {} --plan {}'.format(resource_group, webapp_name, plan_name))
8993
self.cmd('webapp auth config-version show -g {} -n {}'.format(resource_group, webapp_name)).assert_with_checks([
@@ -92,22 +96,26 @@ def test_authV2_auth(self, resource_group):
9296

9397
# testing show command for newly created app and initial fields
9498
self.cmd('webapp auth show -g {} -n {}'.format(resource_group, webapp_name)).assert_with_checks([
95-
JMESPathCheck('properties', {})
99+
JMESPathCheck('properties.platform.enabled', False)
96100
])
101+
102+
self.cmd('webapp auth config-version upgrade -g {} -n {}'.format(resource_group, webapp_name))
97103

98104
# # update and verify
99105
self.cmd('webapp auth update -g {} -n {} --enabled true --runtime-version 1.2.8'
100106
.format(resource_group, webapp_name)).assert_with_checks([
101-
JMESPathCheck('platform', "{'enabled': True, 'runtimeVersion': '1.2.8'}")
107+
JMESPathCheck('platform.enabled', True),
108+
JMESPathCheck('platform.runtimeVersion', '1.2.8')
102109
])
103110

104111

105112
@ResourceGroupPreparer(name_prefix='cli_test_authV2')
113+
@AllowLargeResponse()
106114
def test_authV2_authclassic(self, resource_group):
107115
webapp_name = self.create_random_name('webapp-authentication-test', 40)
108116
plan_name = self.create_random_name('webapp-authentication-plan', 40)
109117
self.cmd(
110-
'appservice plan create -g {} -n {} --sku S1'.format(resource_group, plan_name))
118+
'appservice plan create -g {} -n {} --sku S1 --location westus2'.format(resource_group, plan_name))
111119
self.cmd(
112120
'webapp create -g {} -n {} --plan {}'.format(resource_group, webapp_name, plan_name))
113121
self.cmd('webapp auth config-version show -g {} -n {}'.format(resource_group, webapp_name)).assert_with_checks([
@@ -154,3 +162,57 @@ def test_authV2_authclassic(self, resource_group):
154162
JMESPathCheck('facebookAppId', 'facebook_id')]).get_output_in_json()
155163

156164
self.assertIn('https://audience1', result['allowedAudiences'])
165+
166+
@ResourceGroupPreparer(name_prefix='cli_test_authV2')
167+
@AllowLargeResponse()
168+
def test_authV2_excluded_paths_parsing(self, resource_group):
169+
webapp_name = self.create_random_name('webapp-authentication-test', 40)
170+
plan_name = self.create_random_name('webapp-authentication-plan', 40)
171+
self.cmd(
172+
'appservice plan create -g {} -n {} --sku S1 --location westus2'.format(resource_group, plan_name))
173+
self.cmd(
174+
'webapp create -g {} -n {} --plan {}'.format(resource_group, webapp_name, plan_name))
175+
self.cmd('webapp auth config-version show -g {} -n {}'.format(resource_group, webapp_name)).assert_with_checks([
176+
JMESPathCheck('configVersion', 'v1')
177+
])
178+
179+
self.cmd('webapp auth show -g {} -n {}'.format(resource_group, webapp_name)).assert_with_checks([
180+
JMESPathCheck('properties.platform.enabled', False)
181+
])
182+
self.cmd('webapp auth config-version upgrade -g {} -n {}'.format(resource_group, webapp_name))
183+
184+
# # update and verify
185+
# test single path
186+
self.cmd('webapp auth update -g {} -n {} --enabled true --excluded-paths "/health"'
187+
.format(resource_group, webapp_name)).assert_with_checks([
188+
JMESPathCheck('platform.enabled', True),
189+
JMESPathCheck('globalValidation.excludedPaths[0]', '/health')
190+
])
191+
192+
# test multiple comma separated paths
193+
self.cmd('webapp auth update -g {} -n {} --excluded-paths "/health,/status,/metrics"'
194+
.format(resource_group, webapp_name)).assert_with_checks([
195+
JMESPathCheck('globalValidation.excludedPaths[0]', '/health'),
196+
JMESPathCheck('globalValidation.excludedPaths[1]', '/status'),
197+
JMESPathCheck('globalValidation.excludedPaths[2]', '/metrics')
198+
])
199+
200+
# test JSON array format
201+
self.cmd('webapp auth update -g {} -n {} --excluded-paths \'["/api/health", "/api/status"]\''
202+
.format(resource_group, webapp_name)).assert_with_checks([
203+
JMESPathCheck('globalValidation.excludedPaths[0]', '/api/health'),
204+
JMESPathCheck('globalValidation.excludedPaths[1]', '/api/status')
205+
])
206+
207+
# test paths with special characters
208+
self.cmd('webapp auth update -g {} -n {} --excluded-paths "/api/v1/health,/webhook/callback"'
209+
.format(resource_group, webapp_name)).assert_with_checks([
210+
JMESPathCheck('globalValidation.excludedPaths[0]', '/api/v1/health'),
211+
JMESPathCheck('globalValidation.excludedPaths[1]', '/webhook/callback')
212+
])
213+
214+
# test single path without leading slash
215+
self.cmd('webapp auth update -g {} -n {} --excluded-paths "public"'
216+
.format(resource_group, webapp_name)).assert_with_checks([
217+
JMESPathCheck('globalValidation.excludedPaths[0]', 'public')
218+
])

src/authV2/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from distutils import log as logger
1515
logger.warn("Wheel is not available, disabling bdist_wheel hook")
1616

17-
VERSION = '1.0.0'
17+
VERSION = '1.0.1'
1818

1919
# The full list of classifiers is available at
2020
# https://pypi.python.org/pypi?%3Aaction=list_classifiers

0 commit comments

Comments
 (0)