diff --git a/.gitignore b/.gitignore index e9a4f5e..cb71bff 100644 --- a/.gitignore +++ b/.gitignore @@ -138,4 +138,7 @@ dmypy.json secrets.yml .vscode .DS_Store -compiledstatic/ \ No newline at end of file +compiledstatic/ + +# Pycharm +.idea diff --git a/TEMPLATE.env b/TEMPLATE.env index c7e66ba..7a620bb 100644 --- a/TEMPLATE.env +++ b/TEMPLATE.env @@ -72,4 +72,7 @@ SHOW_SHYNET_VERSION=True # CELERY_BROKER_URL=redis://redis.default.svc.cluster.local/1 # Should Shynet show third-party icons in the dashboard? -SHOW_THIRD_PARTY_ICONS=True \ No newline at end of file +SHOW_THIRD_PARTY_ICONS=True + +# Should Shynet block collection of IP addresses globally? +BLOCK_ALL_IPS=False \ No newline at end of file diff --git a/shynet/analytics/tasks.py b/shynet/analytics/tasks.py index 75b8524..27f7c3f 100644 --- a/shynet/analytics/tasks.py +++ b/shynet/analytics/tasks.py @@ -116,7 +116,7 @@ def ingress_request( return session = Session.objects.create( service=service, - ip=ip if service.collect_ips else None, + ip=ip if service.collect_ips and not settings.BLOCK_ALL_IPS else None, user_agent=user_agent, identifier=identifier.strip(), browser=ua.browser.family or "", diff --git a/shynet/dashboard/forms.py b/shynet/dashboard/forms.py index 9a926e0..d07ea5f 100644 --- a/shynet/dashboard/forms.py +++ b/shynet/dashboard/forms.py @@ -1,5 +1,6 @@ from allauth.account.admin import EmailAddress from django import forms +from django.conf import settings from django.utils.translation import gettext_lazy as _ from core.models import Service, User @@ -33,7 +34,6 @@ class ServiceForm(forms.ModelForm): labels = { "origins": "Allowed origins", "respect_dnt": "Respect DNT", - "collect_ips": "Collect IP addresses", "ignored_ips": "Ignored IP addresses", "ignore_robots": "Ignore robots", "hide_referrer_regex": "Hide specific referrers", @@ -46,13 +46,25 @@ class ServiceForm(forms.ModelForm): "At what origins does the service operate? Use commas to separate multiple values. 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.", "ignored_ips": "A comma-separated list of IP addresses or IP ranges (IPv4 and IPv6) to exclude from tracking (e.g., '192.168.0.2, 127.0.0.1/32').", "ignore_robots": "Should sessions generated by bots be excluded from tracking?", "hide_referrer_regex": "Any referrers that match this RegEx will not be listed in the referrer summary. Sessions will still be tracked normally. No effect if left blank.", "script_inject": "Optional additional JavaScript to inject at the end of the Shynet script. This code will be injected on every page where this service is installed.", } + collect_ips = forms.BooleanField( + help_text="IP address collection is disabled globally by your administrator." if settings.BLOCK_ALL_IPS else "Should individual IP addresses be collected? IP metadata (location, host, etc) will still be collected.", + widget=forms.RadioSelect(choices=[(True, "Yes"), (False, "No")]), + initial=False if settings.BLOCK_ALL_IPS else True, + required=False, + disabled=settings.BLOCK_ALL_IPS + ) + + def clean_collect_ips(self): + collect_ips = self.cleaned_data["collect_ips"] + # Forces collect IPs to be false if it is disabled globally + return False if settings.BLOCK_ALL_IPS else collect_ips + collaborators = forms.CharField( help_text="Which users on this Shynet instance should have read-only access to this service? (Comma separated list of emails.)", required=False, diff --git a/shynet/shynet/settings.py b/shynet/shynet/settings.py index e9aa568..c467e9c 100644 --- a/shynet/shynet/settings.py +++ b/shynet/shynet/settings.py @@ -321,3 +321,6 @@ SHOW_SHYNET_VERSION = os.getenv("SHOW_SHYNET_VERSION", "True") == "True" # Should Shynet show third-party icons in the dashboard? SHOW_THIRD_PARTY_ICONS = os.getenv("SHOW_THIRD_PARTY_ICONS", "True") == "True" + +# Should Shynet never collect any IP? +BLOCK_ALL_IPS = os.getenv("BLOCK_ALL_IPS", "False") == "True"