diff --git a/TEMPLATE.env b/TEMPLATE.env
index 8ed1fba..15c2116 100644
--- a/TEMPLATE.env
+++ b/TEMPLATE.env
@@ -42,8 +42,9 @@ SESSION_MEMORY_TIMEOUT=1800
# them to be able to create services of their own.
ONLY_SUPERUSERS_CREATE=True
-# Whether to perform checks and setup at startup. For most setups,
-# the recommended value is True.
+# Whether to perform checks and setup at startup, including applying unapplied
+# migrations. For most setups, the recommended value is True. Defaults to True.
+# Will skip only if value is False.
PERFORM_CHECKS_AND_SETUP=True
# Your admin user's email. A temporary password will be printed
diff --git a/shynet/analytics/migrations/0003_auto_20200502_1227.py b/shynet/analytics/migrations/0003_auto_20200502_1227.py
new file mode 100644
index 0000000..7c71b33
--- /dev/null
+++ b/shynet/analytics/migrations/0003_auto_20200502_1227.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.5 on 2020-05-02 16:27
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('analytics', '0002_auto_20200415_1742'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='session',
+ name='ip',
+ field=models.GenericIPAddressField(db_index=True, null=True),
+ ),
+ ]
diff --git a/shynet/analytics/models.py b/shynet/analytics/models.py
index 30c747e..460a182 100644
--- a/shynet/analytics/models.py
+++ b/shynet/analytics/models.py
@@ -39,7 +39,7 @@ class Session(models.Model):
default="OTHER",
)
os = models.TextField()
- ip = models.GenericIPAddressField(db_index=True)
+ ip = models.GenericIPAddressField(db_index=True, null=True)
# GeoIP data
asn = models.TextField(blank=True)
diff --git a/shynet/analytics/tasks.py b/shynet/analytics/tasks.py
index 4de5374..7da239b 100644
--- a/shynet/analytics/tasks.py
+++ b/shynet/analytics/tasks.py
@@ -103,7 +103,7 @@ def ingress_request(
device_type = "DESKTOP"
session = Session.objects.create(
service=service,
- ip=ip,
+ ip=ip if service.collect_ips else None,
user_agent=user_agent,
identifier=identifier.strip(),
browser=ua.browser.family or "",
diff --git a/shynet/core/migrations/0004_service_collect_ips.py b/shynet/core/migrations/0004_service_collect_ips.py
new file mode 100644
index 0000000..f5f48fb
--- /dev/null
+++ b/shynet/core/migrations/0004_service_collect_ips.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.0.5 on 2020-05-02 16:22
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('core', '0003_service_respect_dnt'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='service',
+ name='collect_ips',
+ field=models.BooleanField(default=True),
+ ),
+ ]
diff --git a/shynet/core/models.py b/shynet/core/models.py
index ab674c7..82380fc 100644
--- a/shynet/core/models.py
+++ b/shynet/core/models.py
@@ -42,6 +42,7 @@ class Service(models.Model):
max_length=2, choices=SERVICE_STATUSES, default=ACTIVE, db_index=True
)
respect_dnt = models.BooleanField(default=True)
+ collect_ips = models.BooleanField(default=True)
class Meta:
ordering = ["name", "uuid"]
diff --git a/shynet/dashboard/forms.py b/shynet/dashboard/forms.py
index 3c91995..54cb31f 100644
--- a/shynet/dashboard/forms.py
+++ b/shynet/dashboard/forms.py
@@ -8,15 +8,17 @@ from core.models import Service, User
class ServiceForm(forms.ModelForm):
class Meta:
model = Service
- fields = ["name", "link", "respect_dnt", "origins", "collaborators"]
+ fields = ["name", "link", "respect_dnt", "collect_ips", "origins", "collaborators"]
widgets = {
"name": forms.TextInput(),
"origins": forms.TextInput(),
"respect_dnt": forms.RadioSelect(choices=[(True, "Yes"), (False, "No")]),
+ "collect_ips": forms.RadioSelect(choices=[(True, "Yes"), (False, "No")]),
}
labels = {
"origins": "Allowed Hostnames",
"respect_dnt": "Respect DNT",
+ "collect_ips": "Collect IP addresses"
}
help_texts = {
"name": _("What should the service be called?"),
@@ -25,6 +27,7 @@ class ServiceForm(forms.ModelForm):
"At what hostnames does the service operate? This sets CORS headers, so use '*' if you're not sure (or don't care)."
),
"respect_dnt": "Should visitors who have enabled Do Not Track be excluded from all data?",
+ "collect_ips": "Should individual IP addresses be collected? IP metadata (location, host, etc) will still be collected."
}
collaborators = forms.CharField(
diff --git a/shynet/dashboard/templates/dashboard/includes/service_form.html b/shynet/dashboard/templates/dashboard/includes/service_form.html
index 59312d5..c92e653 100644
--- a/shynet/dashboard/templates/dashboard/includes/service_form.html
+++ b/shynet/dashboard/templates/dashboard/includes/service_form.html
@@ -8,5 +8,6 @@
IP
-{{session.ip|truncatechars:"16"}}
+{{session.ip|default:"Not Collected"|truncatechars:"16"}}