def signup_to_team_view(request, token): if request.user.is_authenticated: return redirect('/') if not token: return redirect('/') if not User.objects.exists(): return redirect('/setup_admin') try: team = Team.objects.get(signup_token=token) except Team.DoesNotExist: return redirect('/') if request.method == 'POST': email = request.POST['email'] password = request.POST['password'] first_name=request.POST.get('name') email_opt_in=request.POST.get('emailOptIn') if email_opt_in == 'on': email_opt_in = True try: user = User.objects.create_user(email=email, password=password, first_name=first_name, email_opt_in=email_opt_in) except: return render_template('signup_to_team.html', request=request, context={'email': email, 'error': True, 'team': team, 'signup_token': token}) login(request, user, backend='django.contrib.auth.backends.ModelBackend') team.users.add(user) team.save() posthoganalytics.capture(user.distinct_id, 'user signed up', properties={'is_first_user': False}) posthoganalytics.identify(user.distinct_id, {'email_opt_in': user.email_opt_in}) return redirect('/') return render_template('signup_to_team.html', request, context={'team': team, 'signup_token': token})
def create(self, validated_data, **kwargs): is_first_user: bool = not User.objects.exists() realm: str = "cloud" if getattr(settings, "MULTI_TENANCY", False) else "hosted" company_name = validated_data.pop("company_name", validated_data["first_name"]) self._organization, self._team, self._user = User.objects.bootstrap( company_name=company_name, **validated_data) user = self._user login( self.context["request"], user, backend="django.contrib.auth.backends.ModelBackend", ) posthoganalytics.capture( user.distinct_id, "user signed up", properties={ "is_first_user": is_first_user, "is_organization_first_user": True }, ) posthoganalytics.identify( user.distinct_id, properties={ "email": user.email, "realm": realm, "ee_available": settings.EE_AVAILABLE }, ) return user
def setup_admin(request): if User.objects.exists(): return redirect('/login') if request.method == 'GET': if request.user.is_authenticated: return redirect('/') return render_template('setup_admin.html', request) if request.method == 'POST': email = request.POST['email'] password = request.POST['password'] company_name = request.POST.get('company_name') is_first_user = not User.objects.exists() try: user = User.objects.create_user(email=email, password=password, first_name=request.POST.get('name')) except: return render_template('setup_admin.html', request=request, context={'error': True, 'email': request.POST['email'], 'company_name': request.POST.get('company_name'), 'name': request.POST.get('name')}) Team.objects.create_with_data(users=[user], name=company_name) login(request, user, backend='django.contrib.auth.backends.ModelBackend') posthoganalytics.capture(user.distinct_id, 'user signed up', properties={'is_first_user': is_first_user}) posthoganalytics.identify(user.distinct_id, properties={ 'email': user.email, 'company_name': company_name, 'name': user.first_name }) return redirect('/')
def setup_admin(request): if User.objects.exists(): return redirect("/login") if request.method == "GET": if request.user.is_authenticated: return redirect("/") return render_template("setup_admin.html", request) if request.method == "POST": email = request.POST["email"] password = request.POST["password"] company_name = request.POST.get("company_name") email_opt_in = request.POST.get("emailOptIn") == "on" is_first_user = not User.objects.exists() user = User.objects.create_user( email=email, password=password, first_name=request.POST.get("name"), email_opt_in=email_opt_in, ) Team.objects.create_with_data(users=[user], name=company_name) login(request, user, backend="django.contrib.auth.backends.ModelBackend") posthoganalytics.capture( user.distinct_id, "user signed up", properties={"is_first_user": is_first_user}, ) posthoganalytics.identify( user.distinct_id, properties={ "email": user.email, "company_name": company_name, "name": user.first_name, }, ) return redirect("/")
def create(self, validated_data, **kwargs): is_instance_first_user: bool = not User.objects.exists() company_name = validated_data.pop("company_name", validated_data["first_name"]) self._organization, self._team, self._user = User.objects.bootstrap( company_name=company_name, **validated_data) user = self._user login( self.context["request"], user, backend="django.contrib.auth.backends.ModelBackend", ) posthoganalytics.identify( user.distinct_id, { "is_first_user": is_instance_first_user, "is_organization_first_user": True }, ) posthoganalytics.capture( user.distinct_id, "user signed up", properties={ "is_first_user": is_instance_first_user, "is_organization_first_user": True }, ) return user
def report_user_signed_up( distinct_id: str, is_instance_first_user: bool, is_organization_first_user: bool, new_onboarding_enabled: bool = False, backend_processor: str = "", # which serializer/view processed the request social_provider: str = "", # which third-party provider processed the login (empty = no third-party) ) -> None: """ Reports that a new user has joined. Only triggered when a new user is actually created (i.e. when an existing user joins a new organization, this event is **not** triggered; see `report_user_joined_organization`). """ props = { "is_first_user": is_instance_first_user, "is_organization_first_user": is_organization_first_user, "new_onboarding_enabled": new_onboarding_enabled, "signup_backend_processor": backend_processor, "signup_social_provider": social_provider, "realm": get_instance_realm(), } # TODO: This should be $set_once as user props. posthoganalytics.identify(distinct_id, props) posthoganalytics.capture(distinct_id, "user signed up", properties=props)
def create(self, validated_data): company_name = validated_data.pop("company_name", "") is_first_user: bool = not User.objects.exists() realm: str = "cloud" if not MULTI_TENANCY_MISSING else "hosted" if self.context["request"].user.is_authenticated: raise serializers.ValidationError("Authenticated users may not create additional teams.") if not is_first_user and MULTI_TENANCY_MISSING: raise serializers.ValidationError("This instance does not support multiple teams.") with transaction.atomic(): user = User.objects.create_user(**validated_data) self._team = Team.objects.create_with_data(users=[user], name=company_name) login( self.context["request"], user, backend="django.contrib.auth.backends.ModelBackend", ) posthoganalytics.capture( user.distinct_id, "user signed up", properties={"is_first_user": is_first_user, "is_team_first_user": True}, ) posthoganalytics.identify( user.distinct_id, properties={"email": user.email, "realm": realm, "ee_available": settings.EE_AVAILABLE}, ) return user
def user(request): if not request.user.is_authenticated: return HttpResponse("Unauthorized", status=401) team = request.user.team_set.get() if request.method == "PATCH": data = json.loads(request.body) if "team" in data: team.app_urls = data["team"].get("app_urls", team.app_urls) team.opt_out_capture = data["team"].get("opt_out_capture", team.opt_out_capture) team.slack_incoming_webhook = data["team"].get("slack_incoming_webhook", team.slack_incoming_webhook) team.anonymize_ips = data["team"].get("anonymize_ips", team.anonymize_ips) team.completed_snippet_onboarding = data["team"].get( "completed_snippet_onboarding", team.completed_snippet_onboarding ) team.save() if "user" in data: request.user.email_opt_in = data["user"].get("email_opt_in", request.user.email_opt_in) request.user.anonymize_data = data["user"].get("anonymize_data", request.user.anonymize_data) request.user.toolbar_mode = data["user"].get("toolbar_mode", request.user.toolbar_mode) posthoganalytics.identify( request.user.distinct_id, { "email_opt_in": request.user.email_opt_in, "anonymize_data": request.user.anonymize_data, "email": request.user.email if not request.user.anonymize_data else None, "is_signed_up": True, }, ) request.user.save() return JsonResponse( { "id": request.user.pk, "distinct_id": request.user.distinct_id, "name": request.user.first_name, "email": request.user.email, "has_events": Event.objects.filter(team=team).exists(), "email_opt_in": request.user.email_opt_in, "anonymize_data": request.user.anonymize_data, "toolbar_mode": request.user.toolbar_mode, "team": { "app_urls": team.app_urls, "api_token": team.api_token, "signup_token": team.signup_token, "opt_out_capture": team.opt_out_capture, "anonymize_ips": team.anonymize_ips, "slack_incoming_webhook": team.slack_incoming_webhook, "event_names": team.event_names, "event_properties": team.event_properties, "event_properties_numerical": team.event_properties_numerical, "completed_snippet_onboarding": team.completed_snippet_onboarding, }, "opt_out_capture": os.environ.get("OPT_OUT_CAPTURE"), "posthog_version": settings.VERSION if hasattr(settings, "VERSION") else None, } )
def setup_admin(request): if User.objects.exists(): return redirect("/login") if request.method == "GET": if request.user.is_authenticated: return redirect("/") try: return render_template("setup_admin.html", request) except TemplateDoesNotExist: return HttpResponse( "Frontend not built yet. Please try again shortly or build manually using <code>./bin/start-frontend</code>" ) if request.method == "POST": email = request.POST["email"] password = request.POST["password"] company_name = request.POST.get("company_name") name = request.POST.get("name") email_opt_in = request.POST.get("emailOptIn") == "on" is_first_user = not User.objects.exists() valid_inputs = (is_input_valid("name", name) and is_input_valid("email", email) and is_input_valid("password", password) and is_input_valid("company", company_name)) if not valid_inputs: return render_template( "setup_admin.html", request=request, context={ "email": email, "name": name, "invalid_input": True, "company": company_name }, ) user = User.objects.create_user( email=email, password=password, first_name=name, email_opt_in=email_opt_in, ) team = Team.objects.create_with_data(users=[user], name=company_name) login(request, user, backend="django.contrib.auth.backends.ModelBackend") posthoganalytics.capture( user.distinct_id, "user signed up", properties={"is_first_user": is_first_user}, ) posthoganalytics.identify( user.distinct_id, properties={ "email": user.email, "company_name": company_name, "team_id": team.pk, # TO-DO: handle multiple teams "is_team_first_user": True, }, ) return redirect("/")
def signup_to_team_view(request, token): if request.user.is_authenticated: return redirect("/") if not token: return redirect("/") if not User.objects.exists(): return redirect("/setup_admin") try: team = Team.objects.get(signup_token=token) except Team.DoesNotExist: return redirect("/") if request.method == "POST": email = request.POST["email"] password = request.POST["password"] first_name = request.POST.get("name") email_opt_in = request.POST.get("emailOptIn") == "on" valid_inputs = (is_input_valid("name", first_name) and is_input_valid("email", email) and is_input_valid("password", password)) email_exists = User.objects.filter(email=email).exists() if email_exists or not valid_inputs: return render_template( "signup_to_team.html", request=request, context={ "email": email, "name": first_name, "error": email_exists, "invalid_input": not valid_inputs, "team": team, "signup_token": token, }, ) user = User.objects.create_user( email=email, password=password, first_name=first_name, email_opt_in=email_opt_in, ) login(request, user, backend="django.contrib.auth.backends.ModelBackend") team.users.add(user) team.save() posthoganalytics.capture(user.distinct_id, "user signed up", properties={"is_first_user": False}) posthoganalytics.identify(user.distinct_id, {"email_opt_in": user.email_opt_in}) return redirect("/") return render_template("signup_to_team.html", request, context={ "team": team, "signup_token": token })
def report_onboarding_completed(organization: Organization, current_user: User) -> None: """ Reports that the `new-onboarding-2822` has been completed. """ team_members_count = organization.members.count() # TODO: This should be $set_once as user props. posthoganalytics.identify(current_user.distinct_id, {"onboarding_completed": True}) posthoganalytics.capture( current_user.distinct_id, "onboarding completed", properties={"team_members_count": team_members_count}, )
def user(request): if not request.user.is_authenticated: return HttpResponse('Unauthorized', status=401) team = request.user.team_set.get() if request.method == 'PATCH': data = json.loads(request.body) if 'team' in data: team.app_urls = data['team'].get('app_urls', team.app_urls) team.opt_out_capture = data['team'].get('opt_out_capture', team.opt_out_capture) team.slack_incoming_webhook = data['team'].get( 'slack_incoming_webhook', team.slack_incoming_webhook) team.save() if 'user' in data: request.user.email_opt_in = data['user'].get('email_opt_in') posthoganalytics.identify( request.user.distinct_id, {'email_opt_in': request.user.email_opt_in}) request.user.save() return JsonResponse({ 'id': request.user.pk, 'distinct_id': request.user.distinct_id, 'name': request.user.first_name, 'email': request.user.email, 'has_events': Event.objects.filter(team=team).exists(), 'email_opt_in': request.user.email_opt_in, 'team': { 'app_urls': team.app_urls, 'api_token': team.api_token, 'signup_token': team.signup_token, 'opt_out_capture': team.opt_out_capture, 'slack_incoming_webhook': team.slack_incoming_webhook, 'event_names': team.event_names, 'event_properties': team.event_properties }, 'posthog_version': settings.VERSION if hasattr(settings, 'VERSION') else None })
def report_user_signed_up( user: User, is_instance_first_user: bool, is_organization_first_user: bool, new_onboarding_enabled: bool = False, backend_processor: str = "", # which serializer/view processed the request social_provider: str = "", # which third-party provider processed the login (empty = no third-party) user_analytics_metadata: Optional[ dict] = None, # analytics metadata taken from the User object org_analytics_metadata: Optional[ dict] = None, # analytics metadata taken from the Organization object ) -> None: """ Reports that a new user has joined. Only triggered when a new user is actually created (i.e. when an existing user joins a new organization, this event is **not** triggered; see `report_user_joined_organization`). """ props = { "is_first_user": is_instance_first_user, "is_organization_first_user": is_organization_first_user, "new_onboarding_enabled": new_onboarding_enabled, "signup_backend_processor": backend_processor, "signup_social_provider": social_provider, "realm": get_instance_realm(), } if user_analytics_metadata is not None: props.update(user_analytics_metadata) if org_analytics_metadata is not None: for k, v in org_analytics_metadata.items(): props[f"org__{k}"] = v # TODO: This should be $set_once as user props. posthoganalytics.identify(user.distinct_id, props) posthoganalytics.capture( user.distinct_id, "user signed up", properties=props, groups=groups(user.organization, user.team), )
def signup_view(request): if request.method == 'GET': if request.user.is_authenticated: return redirect('/') if not User.objects.exists(): return redirect('/setup_admin') return render_template('signup.html', request) if request.method == 'POST': email = request.POST['email'] password = request.POST['password'] company_name = request.POST.get('company_name') is_first_user = not User.objects.exists() try: user = User.objects.create_user( email=email, password=password, first_name=request.POST.get('name')) except: return render_template('signup.html', request=request, context={ 'error': True, 'email': request.POST['email'], 'company_name': request.POST.get('company_name'), 'name': request.POST.get('name') }) team = Team.objects.create(name=company_name) team.users.add(user) login(request, user) posthoganalytics.capture(user.distinct_id, 'user signed up', properties={'is_first_user': is_first_user}) posthoganalytics.identify(user.distinct_id, properties={ 'email': user.email, 'company_name': company_name, 'name': user.first_name }) return redirect('/setup')
def create(self, validated_data, **kwargs): is_instance_first_user: bool = not User.objects.exists() company_name = validated_data.pop("company_name", validated_data["first_name"]) self._organization, self._team, self._user = User.objects.bootstrap( company_name=company_name, create_team=self.create_team, **validated_data, ) user = self._user # Temp (due to FF-release [`onboarding-2822`]): Activate the setup/onboarding process if applicable if self.enable_new_onboarding(user): self._organization.setup_section_2_completed = False self._organization.save() login( self.context["request"], user, backend="django.contrib.auth.backends.ModelBackend", ) posthoganalytics.identify( user.distinct_id, { "is_first_user": is_instance_first_user, "is_organization_first_user": True }, ) posthoganalytics.capture( user.distinct_id, "user signed up", properties={ "is_first_user": is_instance_first_user, "is_organization_first_user": True }, ) return user
def report_user_signed_up( distinct_id: str, is_instance_first_user: bool, is_organization_first_user: bool, new_onboarding_enabled: bool = False, backend_processor: str = "", # which serializer/view processed the request social_provider: str = "", # which third-party provider processed the login (empty = no third-party) ) -> None: props = { "is_first_user": is_instance_first_user, "is_organization_first_user": is_organization_first_user, "new_onboarding_enabled": new_onboarding_enabled, "signup_backend_processor": backend_processor, "signup_social_provider": social_provider, } # TODO: This should be $set_once as user props. posthoganalytics.identify(distinct_id, props) posthoganalytics.capture(distinct_id, "user signed up", properties=props)
def signup_to_team_view(request, token): if request.user.is_authenticated: return redirect("/") if not token: return redirect("/") if not User.objects.exists(): return redirect("/preflight") try: team = Team.objects.get(signup_token=token) except Team.DoesNotExist: return redirect("/") if request.method == "POST": email = request.POST["email"] password = request.POST["password"] first_name = request.POST.get("name") email_opt_in = request.POST.get("emailOptIn") == "on" valid_inputs = (is_input_valid("name", first_name) and is_input_valid("email", email) and is_input_valid("password", password)) email_exists = User.objects.filter(email=email).exists() if email_exists or not valid_inputs: return render_template( "signup_to_team.html", request=request, context={ "email": email, "name": first_name, "error": email_exists, "invalid_input": not valid_inputs, "team": team, "signup_token": token, }, ) user = User.objects.create_and_join( team.organization, team, email, password, first_name=first_name, email_opt_in=email_opt_in, ) login(request, user, backend="django.contrib.auth.backends.ModelBackend") posthoganalytics.capture( user.distinct_id, "user signed up", properties={ "is_first_user": False, "first_team_user": False }, ) posthoganalytics.identify( user.distinct_id, { "email": request.user.email if not request.user.anonymize_data else None, "company_name": team.name, "team_id": team.pk, # TO-DO: handle multiple teams "is_team_first_user": False, }, ) return redirect("/") return render_template("signup_to_team.html", request, context={ "team": team, "signup_token": token })
def identify_task(user_id: int) -> None: user = User.objects.get(id=user_id) posthoganalytics.identify(user.distinct_id, user.get_analytics_metadata())
def user(request): organization = request.user.organization organizations = list(request.user.organizations.order_by("-created_at").values("name", "id")) team = request.user.team teams = list(request.user.teams.order_by("-created_at").values("name", "id")) if request.method == "PATCH": data = json.loads(request.body) if "team" in data: team.api_token = data["team"].get("api_token", team.api_token) team.app_urls = data["team"].get("app_urls", team.app_urls) team.opt_out_capture = data["team"].get("opt_out_capture", team.opt_out_capture) team.slack_incoming_webhook = data["team"].get("slack_incoming_webhook", team.slack_incoming_webhook) team.anonymize_ips = data["team"].get("anonymize_ips", team.anonymize_ips) team.session_recording_opt_in = data["team"].get("session_recording_opt_in", team.session_recording_opt_in) team.completed_snippet_onboarding = data["team"].get( "completed_snippet_onboarding", team.completed_snippet_onboarding, ) team.save() if "user" in data: try: request.user.current_organization = request.user.organizations.get( id=data["user"]["current_organization_id"] ) request.user.current_team = request.user.organization.teams.first() except KeyError: pass except ObjectDoesNotExist: return JsonResponse({"detail": "Organization not found for user."}, status=404) except KeyError: pass except ObjectDoesNotExist: return JsonResponse({"detail": "Organization not found for user."}, status=404) try: request.user.current_team = request.user.organization.teams.get(id=int(data["user"]["current_team_id"])) except (KeyError, TypeError): pass except ValueError: return JsonResponse({"detail": "Team ID must be an integer."}, status=400) except ObjectDoesNotExist: return JsonResponse({"detail": "Team not found for user's current organization."}, status=404) request.user.email_opt_in = data["user"].get("email_opt_in", request.user.email_opt_in) request.user.anonymize_data = data["user"].get("anonymize_data", request.user.anonymize_data) request.user.toolbar_mode = data["user"].get("toolbar_mode", request.user.toolbar_mode) posthoganalytics.identify( request.user.distinct_id, { "email_opt_in": request.user.email_opt_in, "anonymize_data": request.user.anonymize_data, "email": request.user.email if not request.user.anonymize_data else None, "is_signed_up": True, "toolbar_mode": request.user.toolbar_mode, "billing_plan": request.user.organization.billing_plan, "is_team_unique_user": (team.users.count() == 1), "team_setup_complete": (team.completed_snippet_onboarding and team.ingested_event), }, ) request.user.save() return JsonResponse( { "id": request.user.pk, "distinct_id": request.user.distinct_id, "name": request.user.first_name, "email": request.user.email, "email_opt_in": request.user.email_opt_in, "anonymize_data": request.user.anonymize_data, "toolbar_mode": request.user.toolbar_mode, "organization": { "id": organization.id, "name": organization.name, "billing_plan": organization.billing_plan, "available_features": organization.available_features, "created_at": organization.created_at, "updated_at": organization.updated_at, "teams": [{"id": team.id, "name": team.name} for team in organization.teams.all().only("id", "name")], }, "organizations": organizations, "team": team and { "id": team.id, "name": team.name, "app_urls": team.app_urls, "api_token": team.api_token, "opt_out_capture": team.opt_out_capture, "anonymize_ips": team.anonymize_ips, "slack_incoming_webhook": team.slack_incoming_webhook, "event_names": team.event_names, "event_properties": team.event_properties, "event_properties_numerical": team.event_properties_numerical, "completed_snippet_onboarding": team.completed_snippet_onboarding, "session_recording_opt_in": team.session_recording_opt_in, "ingested_event": team.ingested_event, }, "teams": teams, "opt_out_capture": os.environ.get("OPT_OUT_CAPTURE"), "posthog_version": VERSION, "is_multi_tenancy": getattr(settings, "MULTI_TENANCY", False), "ee_available": request.user.ee_available, } )
def signup_to_organization_view(request, invite_id): if request.user.is_authenticated or not invite_id: return redirect("/") if not User.objects.exists(): return redirect("/preflight") try: invite: Union[ OrganizationInvite, TeamInviteSurrogate] = OrganizationInvite.objects.select_related( "organization").get(id=invite_id) except (OrganizationInvite.DoesNotExist, ValidationError): try: invite = TeamInviteSurrogate(invite_id) except Team.DoesNotExist: return redirect("/") organization = cast(Organization, invite.organization) if request.method == "POST": email = request.POST["email"] password = request.POST["password"] first_name = request.POST.get("name") email_opt_in = request.POST.get("emailOptIn") == "on" valid_inputs = (is_input_valid("name", first_name) and is_input_valid("email", email) and is_input_valid("password", password)) already_exists = User.objects.filter(email=email).exists() custom_error = None try: invite.validate(user=None, email=email) except ValueError as e: custom_error = str(e) if already_exists or not valid_inputs or custom_error: return render_template( "signup_to_organization.html", request=request, context={ "email": email, "name": first_name, "already_exists": already_exists, "custom_error": custom_error, "invalid_input": not valid_inputs, "organization": organization, "invite_id": invite_id, }, ) user = User.objects.create_and_join(organization, None, email, password, first_name=first_name, email_opt_in=email_opt_in) invite.use(user, prevalidated=True) login(request, user, backend="django.contrib.auth.backends.ModelBackend") posthoganalytics.capture( user.distinct_id, "user signed up", properties={ "is_first_user": False, "first_team_user": False }, ) posthoganalytics.identify( user.distinct_id, { "email": request.user.email if not request.user.anonymize_data else None, "company_name": organization.name, "organization_id": organization.id, "is_organization_first_user": False, }, ) return redirect("/") return render_template("signup_to_organization.html", request, context={ "organization": organization, "invite_id": invite_id })
def user(request): team = request.user.team if request.method == "PATCH": data = json.loads(request.body) if "team" in data: team.app_urls = data["team"].get("app_urls", team.app_urls) team.opt_out_capture = data["team"].get("opt_out_capture", team.opt_out_capture) team.slack_incoming_webhook = data["team"].get( "slack_incoming_webhook", team.slack_incoming_webhook) team.anonymize_ips = data["team"].get("anonymize_ips", team.anonymize_ips) team.completed_snippet_onboarding = data["team"].get( "completed_snippet_onboarding", team.completed_snippet_onboarding, ) # regenerate or disable team signup link signup_state = data["team"].get("signup_state") if signup_state == True: team.signup_token = secrets.token_urlsafe(22) elif signup_state == False: team.signup_token = None team.save() if "user" in data: request.user.email_opt_in = data["user"].get( "email_opt_in", request.user.email_opt_in) request.user.anonymize_data = data["user"].get( "anonymize_data", request.user.anonymize_data) request.user.toolbar_mode = data["user"].get( "toolbar_mode", request.user.toolbar_mode) posthoganalytics.identify( request.user.distinct_id, { "email_opt_in": request.user.email_opt_in, "anonymize_data": request.user.anonymize_data, "email": request.user.email if not request.user.anonymize_data else None, "is_signed_up": True, "toolbar_mode": request.user.toolbar_mode, "billing_plan": request.user.billing_plan, "is_team_unique_user": (team.users.count() == 1), "team_setup_complete": (team.completed_snippet_onboarding and team.ingested_event), }, ) request.user.save() return JsonResponse({ "id": request.user.pk, "distinct_id": request.user.distinct_id, "name": request.user.first_name, "email": request.user.email, "has_events": Event.objects.filter(team=team).exists(), "email_opt_in": request.user.email_opt_in, "anonymize_data": request.user.anonymize_data, "toolbar_mode": request.user.toolbar_mode, "team": { "app_urls": team.app_urls, "api_token": team.api_token, "signup_token": team.signup_token, "opt_out_capture": team.opt_out_capture, "anonymize_ips": team.anonymize_ips, "slack_incoming_webhook": team.slack_incoming_webhook, "event_names": team.event_names, "event_properties": team.event_properties, "event_properties_numerical": team.event_properties_numerical, "completed_snippet_onboarding": team.completed_snippet_onboarding, }, "opt_out_capture": os.environ.get("OPT_OUT_CAPTURE"), "posthog_version": VERSION, "available_features": request.user.available_features, "billing_plan": request.user.billing_plan, "is_multi_tenancy": hasattr(settings, "MULTI_TENANCY"), "ee_available": request.user.ee_available, })
def user(request): organization: Optional[Organization] = request.user.organization organizations = list( request.user.organizations.order_by("-created_at").values( "name", "id")) team: Optional[Team] = request.user.team teams = list( request.user.teams.order_by("-created_at").values("name", "id")) user = cast(User, request.user) if request.method == "PATCH": data = json.loads(request.body) if team is not None and "team" in data: team.app_urls = data["team"].get("app_urls", team.app_urls) team.opt_out_capture = data["team"].get("opt_out_capture", team.opt_out_capture) team.slack_incoming_webhook = data["team"].get( "slack_incoming_webhook", team.slack_incoming_webhook) team.anonymize_ips = data["team"].get("anonymize_ips", team.anonymize_ips) team.session_recording_opt_in = data["team"].get( "session_recording_opt_in", team.session_recording_opt_in) if data["team"].get("plugins_opt_in") is not None: reload_plugins_on_workers() team.plugins_opt_in = data["team"].get("plugins_opt_in", team.plugins_opt_in) team.completed_snippet_onboarding = data["team"].get( "completed_snippet_onboarding", team.completed_snippet_onboarding, ) team.save() if "user" in data: try: user.current_organization = user.organizations.get( id=data["user"]["current_organization_id"]) assert user.organization is not None, "Organization should have been just set" user.current_team = user.organization.teams.first() except (KeyError, ValueError): pass except ObjectDoesNotExist: return JsonResponse( {"detail": "Organization not found for user."}, status=404) except KeyError: pass except ObjectDoesNotExist: return JsonResponse( {"detail": "Organization not found for user."}, status=404) if user.organization is not None: try: user.current_team = user.organization.teams.get( id=int(data["user"]["current_team_id"])) except (KeyError, TypeError): pass except ValueError: return JsonResponse( {"detail": "Team ID must be an integer."}, status=400) except ObjectDoesNotExist: return JsonResponse( { "detail": "Team not found for user's current organization." }, status=404) user.email_opt_in = data["user"].get("email_opt_in", user.email_opt_in) user.anonymize_data = data["user"].get("anonymize_data", user.anonymize_data) user.toolbar_mode = data["user"].get("toolbar_mode", user.toolbar_mode) posthoganalytics.identify( user.distinct_id, { "email_opt_in": user.email_opt_in, "anonymize_data": user.anonymize_data, "email": user.email if not user.anonymize_data else None, "is_signed_up": True, "toolbar_mode": user.toolbar_mode, "billing_plan": user.organization.billing_plan if user.organization is not None else None, "is_team_unique_user": team.users.count() == 1 if team is not None else None, "team_setup_complete": (team.completed_snippet_onboarding and team.ingested_event) if team is not None else None, }, ) user.save() return JsonResponse({ "id": user.pk, "distinct_id": user.distinct_id, "name": user.first_name, "email": user.email, "email_opt_in": user.email_opt_in, "anonymize_data": user.anonymize_data, "toolbar_mode": user.toolbar_mode, "organization": None if organization is None else { "id": organization.id, "name": organization.name, "billing_plan": organization.billing_plan, "available_features": organization.available_features, "created_at": organization.created_at, "updated_at": organization.updated_at, "teams": [{ "id": team.id, "name": team.name } for team in organization.teams.all().only("id", "name")], }, "organizations": organizations, "team": None if team is None else { "id": team.id, "name": team.name, "app_urls": team.app_urls, "api_token": team.api_token, "opt_out_capture": team.opt_out_capture, "anonymize_ips": team.anonymize_ips, "slack_incoming_webhook": team.slack_incoming_webhook, "event_names": team.event_names, "event_names_with_usage": team.event_names_with_usage or [{ "event": event, "volume": None, "usage_count": None } for event in team.event_names], "event_properties": team.event_properties, "event_properties_numerical": team.event_properties_numerical, "event_properties_with_usage": team.event_properties_with_usage or [{ "key": key, "volume": None, "usage_count": None } for key in team.event_properties], "completed_snippet_onboarding": team.completed_snippet_onboarding, "session_recording_opt_in": team.session_recording_opt_in, "plugins_opt_in": team.plugins_opt_in, "ingested_event": team.ingested_event, }, "teams": teams, "has_password": user.has_usable_password(), "opt_out_capture": os.environ.get("OPT_OUT_CAPTURE"), "posthog_version": VERSION, "is_multi_tenancy": getattr(settings, "MULTI_TENANCY", False), "ee_available": user.ee_available, "email_service_available": is_email_available(with_absolute_urls=True), "plugin_access": { "install": can_install_plugins_via_api(), "configure": can_configure_plugins_via_api() }, })