diff --git a/openbook_auth/migrations/0035_user_tracking_consent_ad_partners.py b/openbook_auth/migrations/0035_user_tracking_consent_ad_partners.py new file mode 100644 index 0000000000000000000000000000000000000000..2852475b9a79f9105e4cab691278024b22e162b8 --- /dev/null +++ b/openbook_auth/migrations/0035_user_tracking_consent_ad_partners.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.12 on 2025-02-24 14:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("openbook_auth", "0034_remove_userprofile_cover_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="tracking_consent_ad_partners", + field=models.BooleanField(blank=True, default=None, null=True), + ), + ] diff --git a/openbook_auth/migrations/0036_merge_20250311_1255.py b/openbook_auth/migrations/0036_merge_20250311_1255.py new file mode 100644 index 0000000000000000000000000000000000000000..a9f6e7dadf9cbb584a2ae2ac82304df00ba29893 --- /dev/null +++ b/openbook_auth/migrations/0036_merge_20250311_1255.py @@ -0,0 +1,13 @@ +# Generated by Django 5.0.13 on 2025-03-11 11:55 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("openbook_auth", "0035_user_tracking_consent_ad_partners"), + ("openbook_auth", "0035_userprofile_interests_v2_userprofile_skills_v2"), + ] + + operations = [] diff --git a/openbook_auth/migrations/0037_merge_20250326_1344.py b/openbook_auth/migrations/0037_merge_20250326_1344.py new file mode 100644 index 0000000000000000000000000000000000000000..e22a81fa4feb0d92363420aa8d88055672dbeaf9 --- /dev/null +++ b/openbook_auth/migrations/0037_merge_20250326_1344.py @@ -0,0 +1,13 @@ +# Generated by Django 5.1.7 on 2025-03-26 12:44 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("openbook_auth", "0036_merge_20250311_1255"), + ("openbook_auth", "0036_rename_userprofile_id_user_openbook_au_id_773856_idx"), + ] + + operations = [] diff --git a/openbook_auth/models.py b/openbook_auth/models.py index a912b8777e4f0ae028ce90334c93ef4559e003ce..d124e12b8afc3bcc13c2c9fcfa73095af572d06b 100644 --- a/openbook_auth/models.py +++ b/openbook_auth/models.py @@ -287,6 +287,7 @@ class User(ModelWithUUID, AbstractUser): tracking_consent_analytics = models.BooleanField(blank=True, null=True, default=None) tracking_consent_personalization = models.BooleanField(blank=True, null=True, default=None) + tracking_consent_ad_partners = models.BooleanField(blank=True, null=True, default=None) JWT_TOKEN_TYPE_CHANGE_EMAIL = "CE" JWT_TOKEN_TYPE_PASSWORD_RESET = "PR" @@ -800,6 +801,7 @@ class User(ModelWithUUID, AbstractUser): remove_avatar=False, tracking_consent_analytics=None, tracking_consent_personalization=None, + tracking_consent_ad_partners=None, ) -> None: if url is not None: if len(url) == 0: @@ -849,6 +851,8 @@ class User(ModelWithUUID, AbstractUser): self.tracking_consent_analytics = tracking_consent_analytics if tracking_consent_personalization is not None: self.tracking_consent_personalization = tracking_consent_personalization + if tracking_consent_ad_partners is not None: + self.tracking_consent_ad_partners = tracking_consent_ad_partners if pronouns is not None: self.profile.pronouns = pronouns diff --git a/openbook_auth/schema/mutations.py b/openbook_auth/schema/mutations.py index 272889f7c657faaee6e112e598b1b6745da4dc75..07d39be9e685b34bed0aaed39a8c8fd364ef1d34 100644 --- a/openbook_auth/schema/mutations.py +++ b/openbook_auth/schema/mutations.py @@ -114,6 +114,7 @@ class Mutation: remove_avatar=remove_avatar, tracking_consent_analytics=data.get("tracking_consent_analytics"), tracking_consent_personalization=data.get("tracking_consent_personalization"), + tracking_consent_ad_partners=data.get("tracking_consent_ad_partners"), save=True, ) current_user_fields_after = _capture_user_fields(current_user) diff --git a/openbook_auth/schema/types.py b/openbook_auth/schema/types.py index 6389e20ed3640789dcba8bfe7346a0b37f9bb6d2..45cd99ef1c3f49f22c0f7a444974874c5cbe0f09 100644 --- a/openbook_auth/schema/types.py +++ b/openbook_auth/schema/types.py @@ -49,6 +49,7 @@ class UpdateAuthenticatedUserInput: skills_v2: Optional[List[str]] = strawberry.UNSET tracking_consent_analytics: Optional[bool] = strawberry.UNSET tracking_consent_personalization: Optional[bool] = strawberry.UNSET + tracking_consent_ad_partners: Optional[bool] = strawberry.UNSET @strawberry.input @@ -144,8 +145,10 @@ class User: @strawberry_django.type(UserModel) class AuthenticatedUser(User): + email: str tracking_consent_analytics: Optional[bool] tracking_consent_personalization: Optional[bool] + tracking_consent_ad_partners: Optional[bool] is_employee: bool is_verified: bool role: Optional[UserRole] diff --git a/openbook_auth/serializers/authenticated_user_serializers.py b/openbook_auth/serializers/authenticated_user_serializers.py index a1613c4762b58a08302da941b29979679078bd3e..7d7377c47c19718cd337782724fbd8ad834b3dfd 100644 --- a/openbook_auth/serializers/authenticated_user_serializers.py +++ b/openbook_auth/serializers/authenticated_user_serializers.py @@ -118,3 +118,4 @@ class UpdateAuthenticatedUserSerializer(serializers.Serializer): ) tracking_consent_analytics = serializers.BooleanField(required=False, default=None, allow_null=True) tracking_consent_personalization = serializers.BooleanField(required=False, default=None, allow_null=True) + tracking_consent_ad_partners = serializers.BooleanField(required=False, default=None, allow_null=True) diff --git a/openbook_common/tests/test_tracking.py b/openbook_common/tests/test_tracking.py index 5e8fe285f5305850551d60b6bbdbf17b0a1937de..f75925dd14875580af5efad2142944f7cfd53eb9 100644 --- a/openbook_common/tests/test_tracking.py +++ b/openbook_common/tests/test_tracking.py @@ -14,6 +14,7 @@ class UserForTest(TrackingUser): username: str tracking_consent_analytics: bool tracking_consent_personalization: bool + tracking_consent_ad_partners: bool class TestTracking(unittest.TestCase): @@ -22,7 +23,7 @@ class TestTracking(unittest.TestCase): @mock.patch("posthog.Posthog.capture") def test_no_tracking_without_analytics_consent(self, mock_posthog_capture): - user = UserForTest("donald_trump", False, faker.boolean()) + user = UserForTest("donald_trump", False, faker.boolean(), faker.boolean()) track(user, TrackingEvent("testEvent")) mock_posthog_capture.assert_not_called() @@ -31,7 +32,8 @@ class TestTracking(unittest.TestCase): username = "donald_trump" consent_analytics = True consent_personalization = faker.boolean() - user = UserForTest(username, consent_analytics, consent_personalization) + consent_ad_partners = faker.boolean() + user = UserForTest(username, consent_analytics, consent_personalization, consent_ad_partners) track(user, TrackingEvent("testEvent", {}, 1, 2, 3)) mock_posthog_capture.assert_called_once_with( distinct_id=username, @@ -42,6 +44,7 @@ class TestTracking(unittest.TestCase): "event_version__patch": 3, "trackingConsentAnalytics": consent_analytics, "trackingConsentPersonalization": consent_personalization, + "trackingConsentAdPartners": consent_ad_partners, }, ) @@ -50,7 +53,8 @@ class TestTracking(unittest.TestCase): username = "donald_trump" consent_analytics = True consent_personalization = faker.boolean() - user = UserForTest(username, consent_analytics, consent_personalization) + consent_ad_partners = faker.boolean() + user = UserForTest(username, consent_analytics, consent_personalization, consent_ad_partners) track(user, TrackingEvent("testEvent", {"random_name": "random_value"}, 1, 2, 3)) mock_posthog_capture.assert_called_once_with( distinct_id=username, @@ -61,13 +65,14 @@ class TestTracking(unittest.TestCase): "event_version__patch": 3, "trackingConsentAnalytics": consent_analytics, "trackingConsentPersonalization": consent_personalization, + "trackingConsentAdPartners": consent_ad_partners, "random_name": "random_value", }, ) @mock.patch("posthog.Posthog.capture") def test_adds_default_properties_and_version(self, mock_posthog_capture): - user = UserForTest("donald_trump", True, True) + user = UserForTest("donald_trump", True, True, True) track(user, TrackingEvent("testEvent")) mock_posthog_capture.assert_called_once_with( distinct_id=user.username, @@ -78,13 +83,14 @@ class TestTracking(unittest.TestCase): "event_version__patch": 0, "trackingConsentAnalytics": True, "trackingConsentPersonalization": True, + "trackingConsentAdPartners": True, }, ) @mock.patch("posthog.Posthog.capture") def test_does_not_raise(self, mock_posthog_capture): mock_posthog_capture.side_effect = Exception("Boom!") - user = UserForTest("donald_trump", True, True) + user = UserForTest("donald_trump", True, True, True) # noinspection PyBroadException try: track(user, TrackingEvent("testEvent")) diff --git a/openbook_common/tracking.py b/openbook_common/tracking.py index d39924dc8044c78b5ec9634dbbf8dabff000c86d..2231e54bc49d1736fddddf514709b85b93abd850 100644 --- a/openbook_common/tracking.py +++ b/openbook_common/tracking.py @@ -37,6 +37,7 @@ class TrackingUser(Protocol): username: str tracking_consent_analytics: bool tracking_consent_personalization: bool + tracking_consent_ad_partners: bool def initialize_tracking(config: PostHogConfig): @@ -68,6 +69,7 @@ def track(user: TrackingUser, event: TrackingEvent): "event_version__patch": event.event_version__patch, "trackingConsentAnalytics": user.tracking_consent_analytics, "trackingConsentPersonalization": user.tracking_consent_personalization, + "trackingConsentAdPartners": user.tracking_consent_ad_partners, }, ) except Exception as e: