Skip to content

Commit 410d133

Browse files
committed
WIP: unsuccessful e2e test for POP SHR
1 parent 136065a commit 410d133

File tree

1 file changed

+87
-1
lines changed

1 file changed

+87
-1
lines changed

tests/test_e2e.py

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1164,8 +1164,8 @@ def test_acquire_token_silent_with_an_empty_cache_should_return_none(self):
11641164
# it means MSAL Python is not affected by that.
11651165

11661166

1167+
@unittest.skipUnless(broker_available, "AT POP feature is only supported by using broker")
11671168
class PopTestCase(LabBasedTestCase):
1168-
@unittest.skipUnless(broker_available, "AT POP feature is supported by using broker")
11691169
def test_at_pop_should_contain_pop_scheme_content(self):
11701170
auth_scheme = msal.PopAuthScheme(
11711171
http_method=msal.PopAuthScheme.HTTP_GET,
@@ -1188,6 +1188,92 @@ def test_at_pop_should_contain_pop_scheme_content(self):
11881188
self.assertEqual(payload["p"], auth_scheme._url.path)
11891189
self.assertEqual(payload["nonce"], auth_scheme._nonce)
11901190

1191+
# TODO: Remove this, as ROPC support is removed by Broker-on-Win
1192+
def test_at_pop_via_testingsts_service(self):
1193+
"""Based on https://testingsts.azurewebsites.net/ServerNonce"""
1194+
self.skipTest("ROPC support is removed by Broker-on-Win")
1195+
auth_scheme = msal.PopAuthScheme(
1196+
http_method="POST",
1197+
url="https://www.Contoso.com/Path1/Path2?queryParam1=a&queryParam2=b",
1198+
nonce=requests.get(
1199+
# TODO: Could use ".../missing" and then parse its WWW-Authenticate header
1200+
"https://testingsts.azurewebsites.net/servernonce/get").text,
1201+
)
1202+
config = self.get_lab_user(usertype="cloud")
1203+
config["password"] = self.get_lab_user_secret(config["lab_name"])
1204+
result = self._test_username_password(auth_scheme=auth_scheme, **config)
1205+
self.assertEqual(result["token_type"], "pop")
1206+
shr = result["access_token"]
1207+
payload = json.loads(decode_part(result["access_token"].split(".")[1]))
1208+
logger.debug("AT POP payload = %s", json.dumps(payload, indent=2))
1209+
self.assertEqual(payload["m"], auth_scheme._http_method)
1210+
self.assertEqual(payload["u"], auth_scheme._url.netloc)
1211+
self.assertEqual(payload["p"], auth_scheme._url.path)
1212+
self.assertEqual(payload["nonce"], auth_scheme._nonce)
1213+
1214+
validation = requests.post(
1215+
# TODO: This endpoint does not seem to validate the url
1216+
"https://testingsts.azurewebsites.net/servernonce/validateshr",
1217+
data={"SHR": shr},
1218+
)
1219+
self.assertEqual(validation.status_code, 200)
1220+
1221+
def test_at_pop_calling_pattern(self):
1222+
# The calling pattern was described here:
1223+
# https://identitydivision.visualstudio.com/DevEx/_git/AuthLibrariesApiReview?path=/PoPTokensProtocol/PoP_API_In_MSAL.md&_a=preview&anchor=proposal-2---optional-isproofofposessionsupportedbyclient-helper-(accepted)
1224+
1225+
# It is supposed to call app.is_pop_supported() first,
1226+
# and then fallback to bearer token code path.
1227+
# We skip it here because this test case has not yet initialize self.app
1228+
# assert self.app.is_pop_supported()
1229+
api_endpoint = "https://20.190.132.47/beta/me"
1230+
resp = requests.get(api_endpoint, verify=False)
1231+
self.assertEqual(resp.status_code, 401, "Initial call should end with an http 401 error")
1232+
result = self._get_shr_pop(**dict(
1233+
self.get_lab_user(usertype="cloud"), # This is generally not the current laptop's default AAD account
1234+
scope=["https://graph.microsoft.com/.default"],
1235+
auth_scheme=msal.PopAuthScheme(
1236+
http_method=msal.PopAuthScheme.HTTP_GET,
1237+
url=api_endpoint,
1238+
nonce=self._extract_pop_nonce(resp.headers.get("WWW-Authenticate")),
1239+
),
1240+
))
1241+
resp = requests.get(api_endpoint, verify=False, headers={
1242+
"Authorization": "pop {}".format(result["access_token"]),
1243+
})
1244+
if resp.status_code != 200:
1245+
# TODO https://teams.microsoft.com/l/message/19:[email protected]/1700184847801?context=%7B%22contextType%22%3A%22chat%22%7D
1246+
self.skipTest("We haven't got this end-to-end test case working")
1247+
self.assertEqual(resp.status_code, 200, "POP resource should be accessible")
1248+
1249+
def _extract_pop_nonce(self, www_authenticate):
1250+
# This is a hack for testing purpose only. Do not use this in prod.
1251+
# FYI: There is a www-authenticate package but it falters when encountering realm=""
1252+
import re
1253+
found = re.search(r'nonce="(.+?)"', www_authenticate)
1254+
if found:
1255+
return found.group(1)
1256+
1257+
def _get_shr_pop(
1258+
self, client_id=None, authority=None, scope=None, auth_scheme=None,
1259+
**kwargs):
1260+
result = self._test_acquire_token_interactive(
1261+
# Lab test users tend to get kicked out from WAM, we use local user to test
1262+
client_id=client_id,
1263+
authority=authority,
1264+
scope=scope,
1265+
auth_scheme=auth_scheme,
1266+
**kwargs) # It also tests assertCacheWorksForUser()
1267+
self.assertEqual(result["token_source"], "broker", "POP is only supported by broker")
1268+
self.assertEqual(result["token_type"], "pop")
1269+
payload = json.loads(decode_part(result["access_token"].split(".")[1]))
1270+
logger.debug("AT POP payload = %s", json.dumps(payload, indent=2))
1271+
self.assertEqual(payload["m"], auth_scheme._http_method)
1272+
self.assertEqual(payload["u"], auth_scheme._url.netloc)
1273+
self.assertEqual(payload["p"], auth_scheme._url.path)
1274+
self.assertEqual(payload["nonce"], auth_scheme._nonce)
1275+
return result
1276+
11911277

11921278
if __name__ == "__main__":
11931279
unittest.main()

0 commit comments

Comments
 (0)