From 5b0b74863d86266a838a80baf6c8e0f441d596e8 Mon Sep 17 00:00:00 2001 From: Michael Matloka Date: Wed, 12 Apr 2023 13:11:24 +0200 Subject: [PATCH] fix: Properly bootstrap most property-based feature flags (#15044) --- posthog/models/user.py | 7 ++++--- posthog/test/test_middleware.py | 2 +- posthog/utils.py | 28 +++++++++++++++++++++++----- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/posthog/models/user.py b/posthog/models/user.py index f2a22bfb66271..7910b88f459ef 100644 --- a/posthog/models/user.py +++ b/posthog/models/user.py @@ -1,3 +1,4 @@ +from functools import cached_property from typing import ( Any, Callable, @@ -150,7 +151,7 @@ class User(AbstractUser, UUIDClassicModel): def is_superuser(self) -> bool: # type: ignore return self.is_staff - @property + @cached_property def teams(self): """ All teams the user has access to on any organization, taking into account project based permissioning @@ -182,7 +183,7 @@ def teams(self): return teams.order_by("access_control", "id") - @property + @cached_property def organization(self) -> Optional[Organization]: if self.current_organization is None: if self.current_team is not None: @@ -191,7 +192,7 @@ def organization(self) -> Optional[Organization]: self.save() return self.current_organization - @property + @cached_property def team(self) -> Optional[Team]: if self.current_team is None and self.organization is not None: self.current_team = self.teams.filter(organization=self.current_organization).first() diff --git a/posthog/test/test_middleware.py b/posthog/test/test_middleware.py index 6cc5ffbe9aa86..128c37c2cc64c 100644 --- a/posthog/test/test_middleware.py +++ b/posthog/test/test_middleware.py @@ -92,7 +92,7 @@ class TestAutoProjectMiddleware(APIBaseTest): @classmethod def setUpTestData(cls): super().setUpTestData() - cls.base_app_num_queries = 43 + cls.base_app_num_queries = 42 if settings.MULTI_TENANCY: cls.base_app_num_queries += 2 # Create another team that the user does have access to diff --git a/posthog/utils.py b/posthog/utils.py index 28344d41fd518..7324fc7af77f3 100644 --- a/posthog/utils.py +++ b/posthog/utils.py @@ -53,6 +53,7 @@ if TYPE_CHECKING: from django.contrib.auth.models import AbstractBaseUser, AnonymousUser + from posthog.models import User DATERANGE_MAP = { "minute": datetime.timedelta(minutes=1), @@ -356,7 +357,7 @@ def render_template(template_name: str, request: HttpRequest, context: Dict = {} # Set the frontend app context if not request.GET.get("no-preloaded-app-context"): from posthog.api.team import TeamSerializer - from posthog.api.user import User, UserSerializer + from posthog.api.user import UserSerializer from posthog.user_permissions import UserPermissions from posthog.views import preflight_check @@ -370,7 +371,7 @@ def render_template(template_name: str, request: HttpRequest, context: Dict = {} } if request.user.pk: - user = cast(User, request.user) + user = cast("User", request.user) user_permissions = UserPermissions(user=user, team=user.team) user_serialized = UserSerializer( request.user, context={"request": request, "user_permissions": user_permissions}, many=False @@ -388,9 +389,26 @@ def render_template(template_name: str, request: HttpRequest, context: Dict = {} if posthog_distinct_id: groups = {} - if request.user and request.user.is_authenticated and request.user.organization: - groups = {"organization": str(request.user.organization.id)} - feature_flags = posthoganalytics.get_all_flags(posthog_distinct_id, only_evaluate_locally=True, groups=groups) + group_properties = {} + person_properties = {} + if request.user and request.user.is_authenticated: + user = cast("User", request.user) + person_properties["email"] = user.email + person_properties["joined_at"] = user.date_joined.isoformat() + if user.organization: + groups["organization"] = str(user.organization.id) + group_properties["organization"] = { + "name": user.organization.name, + "created_at": user.organization.created_at.isoformat(), + } + + feature_flags = posthoganalytics.get_all_flags( + posthog_distinct_id, + only_evaluate_locally=True, + person_properties=person_properties, + groups=groups, + group_properties=group_properties, + ) # don't forcefully set distinctID, as this breaks the link for anonymous users coming from `posthog.com`. posthog_bootstrap["featureFlags"] = feature_flags