Skip to content

Commit

Permalink
Closes #790 opt out to boolean and allow anonymizing of data (#821)
Browse files Browse the repository at this point in the history
* Closes #790 opt out to boolean and allow anonymizing of data

* Add deprecated note
  • Loading branch information
timgl committed May 21, 2020
1 parent 9c7d7af commit df48f47
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 28 deletions.
52 changes: 35 additions & 17 deletions frontend/src/layout/LatestVersion.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import { CheckOutlined, WarningOutlined } from '@ant-design/icons'

export function LatestVersion() {
const { user } = useValues(userLogic)
if (user.opt_out_capture) return null
const [latestVersion, setLatestVersion] = useState(null)
const [changelogOpen, setChangelogOpen] = useState(false)
const isApp = window.location.href.indexOf('app.posthog.com') > -1

useEffect(() => {
api.get('https://update.posthog.com/versions').then(versions => {
Expand All @@ -21,25 +23,41 @@ export function LatestVersion() {
<>
{latestVersion ? (
<span style={{ marginRight: 32 }}>
{latestVersion === user.posthog_version && (
{isApp ? (
<Button onClick={() => setChangelogOpen(true)} type="link" style={{ color: 'var(--green)' }}>
<span className="hide-when-small">
<CheckOutlined /> PostHog up-to-date
</span>
<span className="show-when-small">
<CheckOutlined /> {latestVersion}
</span>
</Button>
)}
{latestVersion !== user.posthog_version && (
<Button type="link" onClick={() => setChangelogOpen(true)} style={{ color: 'var(--red)' }}>
<span className="hide-when-small">
<WarningOutlined /> New version available
</span>
<span className="show-when-small">
<WarningOutlined /> Upgrade!
</span>
New features
</Button>
) : (
<span>
{latestVersion === user.posthog_version && (
<Button
onClick={() => setChangelogOpen(true)}
type="link"
style={{ color: 'var(--green)' }}
>
<span className="hide-when-small">
<CheckOutlined /> PostHog up-to-date
</span>
<span className="show-when-small">
<CheckOutlined /> {latestVersion}
</span>
</Button>
)}
{latestVersion !== user.posthog_version && (
<Button
type="link"
onClick={() => setChangelogOpen(true)}
style={{ color: 'var(--red)' }}
>
<span className="hide-when-small">
<WarningOutlined /> New version available
</span>
<span className="show-when-small">
<WarningOutlined /> Upgrade!
</span>
</Button>
)}
</span>
)}
</span>
) : null}
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/scenes/setup/OptOutCapture.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,25 @@ export function OptOutCapture() {
<br />
<br />
We also understand there are many reasons why people don't want to or aren't allowed to send this usage
data. Just tick the box below to opt out of this.
data. If you would like to anonymize your personal usage data, just tick the box below.
<br />
<br />
<Switch
onChange={checked => {
api.update('api/user', {
team: { opt_out_capture: checked },
user: {
anonymize_data: checked,
},
}).then(() => setSaved(true))
}}
defaultChecked={user.team.opt_out_capture}
defaultChecked={user.anonymize_data}
/>
<label
style={{
marginLeft: '10px',
}}
>
Opt-out of sending usage data to PostHog.
Anonymize my data
</label>
{saved && (
<p className="text-success">
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/setup/Setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function Setup() {
<h2 id="password">Change Password</h2>
<ChangePassword />
<Divider />
<h2 id="optout">Opt out of capturing</h2>
<h2 id="optout">Anonymize data collection</h2>
<OptOutCapture />
<Divider />
<h2>Security and feature updates</h2>
Expand Down
2 changes: 1 addition & 1 deletion latest_migrations.manifest
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
admin: 0003_logentry_add_action_flag_choices
auth: 0011_update_proxy_permissions
contenttypes: 0002_remove_content_type_name
posthog: 0054_dashboard_item_color
posthog: 0055_user_anonymize_data
sessions: 0001_initial
social_django: 0008_partial_timestamp
13 changes: 11 additions & 2 deletions posthog/api/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import urllib.parse
import secrets
import json
import os
import posthoganalytics

def user(request):
Expand All @@ -30,8 +31,14 @@ def user(request):
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.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)
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({
Expand All @@ -41,6 +48,7 @@ def user(request):
'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,
'team': {
'app_urls': team.app_urls,
'api_token': team.api_token,
Expand All @@ -50,6 +58,7 @@ def user(request):
'event_names': team.event_names,
'event_properties': team.event_properties
},
'opt_out_capture': os.environ.get('OPT_OUT_CAPTURE'),
'posthog_version': settings.VERSION if hasattr(settings, 'VERSION') else None
})

Expand Down
3 changes: 2 additions & 1 deletion posthog/apps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.apps import AppConfig
from django.conf import settings
import posthoganalytics
import os


class PostHogConfig(AppConfig):
Expand All @@ -9,5 +10,5 @@ class PostHogConfig(AppConfig):

def ready(self):
posthoganalytics.api_key = 'sTMFPsFhdP1Ssg'
if settings.TEST:
if settings.TEST or os.environ.get('OPT_OUT_CAPTURE'):
posthoganalytics.disabled = True
18 changes: 18 additions & 0 deletions posthog/migrations/0055_user_anonymize_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.0.5 on 2020-05-21 12:03

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('posthog', '0054_dashboard_item_color'),
]

operations = [
migrations.AddField(
model_name='user',
name='anonymize_data',
field=models.BooleanField(blank=True, default=False, null=True),
),
]
5 changes: 4 additions & 1 deletion posthog/models/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,16 @@ class Team(models.Model):
models.CharField(max_length=200, null=True, blank=True), default=list
)
name: models.CharField = models.CharField(max_length=200, null=True, blank=True)
opt_out_capture: models.BooleanField = models.BooleanField(default=False)
slack_incoming_webhook: models.CharField = models.CharField(
max_length=200, null=True, blank=True
)
event_names: JSONField = JSONField(default=list)
event_properties: JSONField = JSONField(default=list)

# DEPRECATED: this field is deprecated in favour of OPT_OUT_CAPTURE env variable and anonymized data
# However, we still honor teams that have set this previously
opt_out_capture: models.BooleanField = models.BooleanField(default=False)

objects = TeamManager()

def __str__(self):
Expand Down
3 changes: 3 additions & 0 deletions posthog/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ class User(AbstractUser):
email_opt_in: models.BooleanField = models.BooleanField(
default=False, null=True, blank=True
)
anonymize_data: models.BooleanField = models.BooleanField(
default=False, null=True, blank=True
)

USERNAME_FIELD = "email"
REQUIRED_FIELDS: List[str] = []
Expand Down
1 change: 0 additions & 1 deletion posthog/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ def get_env(key):

WSGI_APPLICATION = 'posthog.wsgi.application'


# Social Auth

SOCIAL_AUTH_POSTGRES_JSONFIELD = True
Expand Down
6 changes: 6 additions & 0 deletions posthog/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from dateutil.relativedelta import relativedelta
from django.utils.timezone import now
from django.conf import settings
from django.db.models import Q
from typing import Dict, Any, List, Union
from django.template.loader import get_template
Expand Down Expand Up @@ -86,6 +87,11 @@ def render_template(template_name: str, request: HttpRequest, context=None) -> H
'opt_out_capture': team.first().opt_out_capture, # type: ignore
})

if os.environ.get('OPT_OUT_CAPTURE'):
context.update({
'opt_out_capture': True
})

if os.environ.get('SENTRY_DSN'):
context.update({
'sentry_dsn': os.environ['SENTRY_DSN']
Expand Down

0 comments on commit df48f47

Please sign in to comment.