구글 계정 식별 회귀를 고정
This commit is contained in:
parent
3a7b6f7760
commit
21bbe3f98d
1 changed files with 87 additions and 3 deletions
|
|
@ -430,6 +430,28 @@ class AuthProviderScaffoldTest(unittest.IsolatedAsyncioTestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(unverified.exception.status_code, 403)
|
self.assertEqual(unverified.exception.status_code, 403)
|
||||||
|
|
||||||
|
def test_google_provider_identity_is_subject_based_and_separates_accounts(
|
||||||
|
self,
|
||||||
|
) -> None:
|
||||||
|
first_login = auth_routes._provider_external_id(
|
||||||
|
"google",
|
||||||
|
"google-subject-a",
|
||||||
|
"first-address@gmail.com",
|
||||||
|
)
|
||||||
|
same_account_new_email = auth_routes._provider_external_id(
|
||||||
|
"google",
|
||||||
|
"google-subject-a",
|
||||||
|
"renamed-address@gmail.com",
|
||||||
|
)
|
||||||
|
different_google_account = auth_routes._provider_external_id(
|
||||||
|
"google",
|
||||||
|
"google-subject-b",
|
||||||
|
"second-address@gmail.com",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(first_login, same_account_new_email)
|
||||||
|
self.assertNotEqual(first_login, different_google_account)
|
||||||
|
|
||||||
async def test_super_admin_email_is_admin_and_auto_approved(self) -> None:
|
async def test_super_admin_email_is_admin_and_auto_approved(self) -> None:
|
||||||
with (
|
with (
|
||||||
patched_settings(
|
patched_settings(
|
||||||
|
|
@ -461,7 +483,7 @@ class AuthProviderScaffoldTest(unittest.IsolatedAsyncioTestCase):
|
||||||
async def test_existing_primary_role_super_admin_persists_admin_access_on_login(
|
async def test_existing_primary_role_super_admin_persists_admin_access_on_login(
|
||||||
self,
|
self,
|
||||||
) -> None:
|
) -> None:
|
||||||
email = "persistent-root@twentyoz.kr"
|
email = "yunchan8804@gmail.com"
|
||||||
existing = _managed_user(email=email, role="learner", admin_access=False)
|
existing = _managed_user(email=email, role="learner", admin_access=False)
|
||||||
auth_sessions._users[existing.user_id] = existing
|
auth_sessions._users[existing.user_id] = existing
|
||||||
auth_sessions._email_index[email] = existing.user_id
|
auth_sessions._email_index[email] = existing.user_id
|
||||||
|
|
@ -478,9 +500,9 @@ class AuthProviderScaffoldTest(unittest.IsolatedAsyncioTestCase):
|
||||||
):
|
):
|
||||||
_, user = await auth_sessions.create_session(
|
_, user = await auth_sessions.create_session(
|
||||||
email=email,
|
email=email,
|
||||||
display_name="Persistent Root",
|
display_name="Yun Chan",
|
||||||
role="learner",
|
role="learner",
|
||||||
external_id="google:persistent-root",
|
external_id="google:yunchan8804",
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(user.role, "learner")
|
self.assertEqual(user.role, "learner")
|
||||||
|
|
@ -705,6 +727,68 @@ class AuthProviderScaffoldTest(unittest.IsolatedAsyncioTestCase):
|
||||||
self.assertIn("$7::boolean", conn.queries[0])
|
self.assertIn("$7::boolean", conn.queries[0])
|
||||||
self.assertIn("$9::boolean", conn.queries[1])
|
self.assertIn("$9::boolean", conn.queries[1])
|
||||||
|
|
||||||
|
async def test_google_oauth_claims_only_exact_normalized_email_placeholder(
|
||||||
|
self,
|
||||||
|
) -> None:
|
||||||
|
class RecordingConn:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.query = ""
|
||||||
|
self.args: tuple[Any, ...] = ()
|
||||||
|
|
||||||
|
async def fetchrow(self, query: str, *args: Any) -> dict[str, Any]:
|
||||||
|
self.query = query
|
||||||
|
self.args = args
|
||||||
|
now = datetime.now(timezone.utc)
|
||||||
|
return {
|
||||||
|
"user_id": "00000000-0000-0000-0000-000000000607",
|
||||||
|
"email": "claim.me@example.com",
|
||||||
|
"display_name": "Claim Me",
|
||||||
|
"role": "learner",
|
||||||
|
"admin_access": False,
|
||||||
|
"account_status": "approved",
|
||||||
|
"cohort": "",
|
||||||
|
"affiliation": "",
|
||||||
|
"created_at": now,
|
||||||
|
"last_seen_at": now,
|
||||||
|
}
|
||||||
|
|
||||||
|
class RecordingAcquire:
|
||||||
|
def __init__(self, conn: RecordingConn) -> None:
|
||||||
|
self.conn = conn
|
||||||
|
|
||||||
|
async def __aenter__(self) -> RecordingConn:
|
||||||
|
return self.conn
|
||||||
|
|
||||||
|
async def __aexit__(self, exc_type, exc, tb) -> None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
class RecordingPool:
|
||||||
|
def __init__(self, conn: RecordingConn) -> None:
|
||||||
|
self.conn = conn
|
||||||
|
|
||||||
|
def acquire(self) -> RecordingAcquire:
|
||||||
|
return RecordingAcquire(self.conn)
|
||||||
|
|
||||||
|
conn = RecordingConn()
|
||||||
|
with patch.object(auth_sessions, "get_pool", return_value=RecordingPool(conn)):
|
||||||
|
user = await auth_sessions.upsert_managed_user(
|
||||||
|
auth_sessions.ManagedUserUpsertInput(
|
||||||
|
email=" Claim.Me@Example.com ",
|
||||||
|
display_name="Claim Me",
|
||||||
|
role="learner",
|
||||||
|
external_id="google:claim-subject",
|
||||||
|
account_status="approved",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(user.email, "claim.me@example.com")
|
||||||
|
self.assertIn("WHERE lower(email) = $2", conn.query)
|
||||||
|
self.assertIn("AND (external_id = $6 OR external_id IS NULL)", conn.query)
|
||||||
|
self.assertIn("WHERE existing.external_id = $1", conn.query)
|
||||||
|
self.assertEqual(conn.args[0], "google:claim-subject")
|
||||||
|
self.assertEqual(conn.args[1], "claim.me@example.com")
|
||||||
|
self.assertEqual(conn.args[5], "email:claim.me@example.com")
|
||||||
|
|
||||||
async def test_google_oauth_promotes_preregistered_pending_user_in_db(self) -> None:
|
async def test_google_oauth_promotes_preregistered_pending_user_in_db(self) -> None:
|
||||||
class RecordingConn:
|
class RecordingConn:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue