Show an existing NetKingdom sign-in before the account site continues it.
The account site said "Not signed in" while Authelia still had a session, and Sign in reused that identity. Ask Authelia who the session cookie is, show that name, and send a fresh sign-in only when a different identity is requested. Assistant: grok Assistant-Session: 01a0d25d-d358-7e13-b84a-d007fbb7e34f
This commit is contained in:
parent
b987a3de9e
commit
560cdeed46
9 changed files with 500 additions and 19 deletions
106
tests/test_account_identity_disclosure.py
Normal file
106
tests/test_account_identity_disclosure.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
"""An existing NetKingdom sign-in is shown before the account site continues it."""
|
||||
import unittest
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
import test_portal_navigation
|
||||
from test_web import invoke
|
||||
|
||||
|
||||
class RecordingLookup:
|
||||
def __init__(self, result):
|
||||
self.result = result
|
||||
self.headers = []
|
||||
|
||||
def username(self, header):
|
||||
self.headers.append(header)
|
||||
if isinstance(self.result, BaseException):
|
||||
raise self.result
|
||||
if callable(self.result):
|
||||
return self.result(header)
|
||||
return self.result
|
||||
|
||||
|
||||
class AccountIdentityDisclosureTests(unittest.TestCase):
|
||||
setUp = test_portal_navigation.PortalNavigationTests.setUp
|
||||
|
||||
def test_confirmed_sign_in_is_named_before_the_account_site_continues(self):
|
||||
def answer(header):
|
||||
if "authelia_session=super-secret-session" in header:
|
||||
return "platform-root"
|
||||
return None
|
||||
|
||||
self.app.identity_lookup = RecordingLookup(answer)
|
||||
cookie = "ue_session=absent; authelia_session=super-secret-session"
|
||||
response, body = invoke(self.app, "/", cookie=cookie)
|
||||
self.assertEqual("200 OK", response["status"])
|
||||
self.assertEqual(1, len(self.app.identity_lookup.headers))
|
||||
self.assertIn(b"NetKingdom sign-in is <strong>platform-root</strong>", body)
|
||||
self.assertIn(b"This account site has no session yet.", body)
|
||||
self.assertIn(b'href="/login">Continue as platform-root', body)
|
||||
self.assertIn(b'href="/login?fresh=1">Use a different identity', body)
|
||||
self.assertNotIn(b"Not signed in", body)
|
||||
self.assertNotIn(b"You are not signed in.", body)
|
||||
self.assertNotIn(b"Signed in as", body)
|
||||
self.assertNotIn(b"super-secret-session", body)
|
||||
self.assertNotIn(b"Active now", body)
|
||||
|
||||
_response, body = invoke(self.app, "/")
|
||||
self.assertIn(b'href="/login">Sign in', body)
|
||||
self.assertIn(b"Not signed in", body)
|
||||
self.assertNotIn(b"platform-root", body)
|
||||
self.assertEqual(2, len(self.app.identity_lookup.headers))
|
||||
|
||||
def test_account_session_is_not_replaced_by_the_netkingdom_cookie(self):
|
||||
self.app.identity_lookup = RecordingLookup("platform-root")
|
||||
_, body = invoke(
|
||||
self.app, "/", cookie="ue_session=member; authelia_session=super-secret-session"
|
||||
)
|
||||
self.assertIn(b"Signed in as", body)
|
||||
self.assertIn(b"sample.user", body)
|
||||
self.assertNotIn(b"platform-root", body)
|
||||
self.assertNotIn(b'href="/login"', body)
|
||||
self.assertEqual([], self.app.identity_lookup.headers)
|
||||
|
||||
def test_lookup_failure_or_unsafe_name_stays_signed_out(self):
|
||||
for result in [TimeoutError("slow"), "<script>alert(1)</script>", "platform root"]:
|
||||
with self.subTest(result=result):
|
||||
self.app.identity_lookup = RecordingLookup(result)
|
||||
_, body = invoke(self.app, "/", cookie="authelia_session=opaque")
|
||||
self.assertIn(b'href="/login">Sign in', body)
|
||||
self.assertIn(b"You are not signed in.", body)
|
||||
self.assertNotIn(b"Signed in as", body)
|
||||
self.assertNotIn(b"<script>", body)
|
||||
self.assertNotIn(b"platform root", body)
|
||||
|
||||
def test_logged_out_and_recovery_name_the_same_sign_in(self):
|
||||
self.app.identity_lookup = RecordingLookup("platform-root")
|
||||
cookie = "authelia_session=super-secret-session"
|
||||
_, logged_out = invoke(self.app, "/logged-out", cookie=cookie)
|
||||
self.assertIn(b"NetKingdom sign-in is <strong>platform-root</strong>", logged_out)
|
||||
self.assertIn(b"This account site has no session yet.", logged_out)
|
||||
self.assertNotIn(b"may still be active", logged_out)
|
||||
self.assertNotIn(b"super-secret-session", logged_out)
|
||||
self.assertIn(b"https://kc.example/account/logout", logged_out)
|
||||
_, recovery = invoke(self.app, "/access-recovery", cookie=cookie)
|
||||
self.assertIn(b"NetKingdom sign-in is <strong>platform-root</strong>", recovery)
|
||||
self.assertNotIn(b"Signed in as", recovery)
|
||||
self.assertIn(b"/logout", recovery)
|
||||
|
||||
def test_different_identity_requests_a_fresh_sign_in(self):
|
||||
response, _body = invoke(self.app, "/login", query="fresh=1")
|
||||
location = response["headers"]["Location"]
|
||||
query = parse_qs(urlparse(location).query)
|
||||
self.assertEqual(["login"], query["prompt"])
|
||||
self.assertEqual(["0"], query["max_age"])
|
||||
self.assertNotIn("acr_values", query)
|
||||
|
||||
def test_query_parameters_do_not_invent_the_shown_identity(self):
|
||||
self.app.identity_lookup = RecordingLookup("platform-root")
|
||||
_, body = invoke(
|
||||
self.app,
|
||||
"/",
|
||||
query="username=forged",
|
||||
cookie="authelia_session=super-secret-session",
|
||||
)
|
||||
self.assertIn(b"platform-root", body)
|
||||
self.assertNotIn(b"forged", body)
|
||||
Loading…
Add table
Add a link
Reference in a new issue