From 7473caa7a5a1d17c50ecf6a4c0f3ba95e9fd4fbd Mon Sep 17 00:00:00 2001 From: groovecoder Date: Mon, 22 Apr 2024 16:48:10 -0500 Subject: [PATCH 1/2] fix MPP-3805: get FxA SocialApp from DB at startup --- privaterelay/apps.py | 7 +++++++ privaterelay/tests/views_tests.py | 2 +- privaterelay/views.py | 14 +++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/privaterelay/apps.py b/privaterelay/apps.py index 1ebef5b29e..63c6bbdb96 100644 --- a/privaterelay/apps.py +++ b/privaterelay/apps.py @@ -81,6 +81,7 @@ def ready(self) -> None: try: del self.fxa_verifying_keys # Clear cache + del self.fxa_social_app # Clear cache except AttributeError: pass @@ -93,3 +94,9 @@ def fxa_verifying_keys(self) -> list[dict[str, Any]]: keys: list[dict[str, Any]] = resp.json()["keys"] return keys return [] + + @cached_property + def fxa_social_app(self) -> Any: + from allauth.socialaccount.models import SocialApp + + return SocialApp.objects.get(provider="fxa") diff --git a/privaterelay/tests/views_tests.py b/privaterelay/tests/views_tests.py index d703de1e4c..47bd80af8f 100644 --- a/privaterelay/tests/views_tests.py +++ b/privaterelay/tests/views_tests.py @@ -237,7 +237,7 @@ def setup_fxa_rp_events( profile.save() # Create FxA app, account, token, etc. - fxa_app: SocialApp = baker.make(SocialApp, provider="fxa") + fxa_app: SocialApp = baker.make(SocialApp, provider="fxa", client_id="test-fxa") fxa_profile_data = { "email": user.email, "locale": "en-US,en;q=0.5", diff --git a/privaterelay/views.py b/privaterelay/views.py index a10c85ebb5..5069e088cd 100644 --- a/privaterelay/views.py +++ b/privaterelay/views.py @@ -165,6 +165,15 @@ def fxa_verifying_keys(reload: bool = False) -> list[dict[str, Any]]: return private_relay_config.fxa_verifying_keys +def fxa_social_app(reload: bool = False) -> SocialApp: + """Get FxA SocialApp from app config or DB.""" + private_relay_config = apps.get_app_config("privaterelay") + assert isinstance(private_relay_config, PrivateRelayConfig) + if reload: + private_relay_config.ready() + return private_relay_config.fxa_social_app + + class FxAEvent(TypedDict): """ FxA Security Event Token (SET) payload, sent to relying parties. @@ -201,7 +210,10 @@ def _verify_jwt_with_fxa_key( ) -> FxAEvent | None: if not verifying_keys: raise Exception("FXA verifying keys are not available.") - social_app = SocialApp.objects.get(provider="fxa") + social_app = fxa_social_app() + if not social_app: + raise Exception("FXA SocialApp is not available.") + assert isinstance(social_app, SocialApp) for verifying_key in verifying_keys: if verifying_key["alg"] == "RS256": public_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(verifying_key)) From 06661e9fe9d846482564d2ae8c48a1fd1681c87e Mon Sep 17 00:00:00 2001 From: groovecoder Date: Tue, 23 Apr 2024 11:56:00 -0500 Subject: [PATCH 2/2] use TYPE_CHECKING to annotate return type as SocialApp --- privaterelay/apps.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/privaterelay/apps.py b/privaterelay/apps.py index 63c6bbdb96..18f9381e4f 100644 --- a/privaterelay/apps.py +++ b/privaterelay/apps.py @@ -2,7 +2,7 @@ import json import os from pathlib import Path -from typing import Any +from typing import TYPE_CHECKING, Any from django.apps import AppConfig from django.conf import settings @@ -13,6 +13,10 @@ ROOT_DIR = os.path.abspath(os.curdir) +if TYPE_CHECKING: + from allauth.socialaccount.models import SocialApp + + def get_profiler_startup_data() -> tuple[str | None, str | None]: from .utils import get_version_info @@ -96,7 +100,7 @@ def fxa_verifying_keys(self) -> list[dict[str, Any]]: return [] @cached_property - def fxa_social_app(self) -> Any: + def fxa_social_app(self) -> "SocialApp": from allauth.socialaccount.models import SocialApp return SocialApp.objects.get(provider="fxa")