From cfe3dac408d7d0cd1baa8259e5ea652cf757eef8 Mon Sep 17 00:00:00 2001 From: "R. Miles McCain" Date: Tue, 14 Apr 2020 09:51:34 -0400 Subject: [PATCH] Polish analytics & add collaboration --- .../a17t/templates/a17t/includes/field.html | 10 +++++ shynet/core/apps.py | 4 +- shynet/core/forms.py | 3 +- shynet/core/rules.py | 6 +-- .../email/password_reset_key_message.txt | 2 +- .../account/password_reset_from_key.html | 2 +- .../account/password_reset_from_key_done.html | 1 + shynet/core/templates/base.html | 8 +++- .../templates/core/includes/session_list.html | 35 +++++++++++++++++ .../core/templates/core/pages/dashboard.html | 2 +- shynet/core/templates/core/pages/service.html | 8 +++- .../core/pages/service_session_list.html | 34 +--------------- .../templates/core/pages/service_update.html | 39 +++++++++++-------- shynet/core/views.py | 22 +++++++++-- shynet/shynet/settings.py | 26 +++++++++++-- 15 files changed, 132 insertions(+), 70 deletions(-) create mode 100644 shynet/core/templates/core/includes/session_list.html diff --git a/shynet/a17t/templates/a17t/includes/field.html b/shynet/a17t/templates/a17t/includes/field.html index e199042..09b1604 100644 --- a/shynet/a17t/templates/a17t/includes/field.html +++ b/shynet/a17t/templates/a17t/includes/field.html @@ -6,6 +6,16 @@ {{ field }} {{ field.label }} + {% elif field|is_multiple_checkbox %} + {% if field.auto_id %} + + {% endif %} + {% for choice in field %} + + {% endfor %} {% elif field|is_radio %} {% if field.auto_id %} diff --git a/shynet/core/apps.py b/shynet/core/apps.py index 5ef1d60..514b70c 100644 --- a/shynet/core/apps.py +++ b/shynet/core/apps.py @@ -1,5 +1,7 @@ from django.apps import AppConfig - class CoreConfig(AppConfig): name = "core" + + # def ready(self): + # import core.rules diff --git a/shynet/core/forms.py b/shynet/core/forms.py index 8c893a3..c56dd85 100644 --- a/shynet/core/forms.py +++ b/shynet/core/forms.py @@ -7,10 +7,11 @@ from .models import Service class ServiceForm(forms.ModelForm): class Meta: model = Service - fields = ["name", "link", "origins"] + fields = ["name", "link", "origins", "collaborators"] widgets = { "name": forms.TextInput(), "origins": forms.TextInput(), + "collaborators": forms.CheckboxSelectMultiple(), } labels = { "origins": "Allowed Hostnames", diff --git a/shynet/core/rules.py b/shynet/core/rules.py index 536b405..1fbdc3b 100644 --- a/shynet/core/rules.py +++ b/shynet/core/rules.py @@ -10,13 +10,13 @@ def is_service_creator(user): @rules.predicate -def is_service_owner(service, user): +def is_service_owner(user, service): return service.owner == user @rules.predicate -def is_service_collaborator(service, user): - return user in service.collaborators.all() +def is_service_collaborator(user, service): + return service.collaborators.filter(pk=user.pk).exists() rules.add_perm("core.view_service", is_service_owner | is_service_collaborator) diff --git a/shynet/core/templates/account/email/password_reset_key_message.txt b/shynet/core/templates/account/email/password_reset_key_message.txt index 8131a77..70b1ac8 100644 --- a/shynet/core/templates/account/email/password_reset_key_message.txt +++ b/shynet/core/templates/account/email/password_reset_key_message.txt @@ -6,7 +6,7 @@ This message can be safely ignored if you did not request a password reset. Clic {{ password_reset_url }} -{% endif %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Thank you, +{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Thank you, {{ site_name }} {% endblocktrans %} {% endautoescape %} diff --git a/shynet/core/templates/account/password_reset_from_key.html b/shynet/core/templates/account/password_reset_from_key.html index 079ca67..c233830 100644 --- a/shynet/core/templates/account/password_reset_from_key.html +++ b/shynet/core/templates/account/password_reset_from_key.html @@ -13,7 +13,7 @@
{% csrf_token %} {{ form|a17t }} - +
{% else %}

{% trans 'Your password is now changed.' %}

diff --git a/shynet/core/templates/account/password_reset_from_key_done.html b/shynet/core/templates/account/password_reset_from_key_done.html index 4b9275f..913e7b6 100644 --- a/shynet/core/templates/account/password_reset_from_key_done.html +++ b/shynet/core/templates/account/password_reset_from_key_done.html @@ -6,4 +6,5 @@ {% block card %}

{% trans 'Your password is now changed.' %}

+ Log In {% endblock %} diff --git a/shynet/core/templates/base.html b/shynet/core/templates/base.html index c4167a4..b502cc2 100644 --- a/shynet/core/templates/base.html +++ b/shynet/core/templates/base.html @@ -48,19 +48,23 @@ {% if can_create %} {% url 'core:service_create' as url %} {% include 'core/includes/sidebar_portal.html' with label="+ Create" url=url %} + +
{% endif %} + {% if user.collaborating_services.all %} -

Collaborations

+

Collaborations

{% for service in user.collaborating_services.all %} {% url 'core:service' service.uuid as url %} {% include 'core/includes/sidebar_portal.html' with label=service.name url=url %} {% endfor %} +
{% endif %} -

Account

+

Account

{% if user.is_authenticated %} diff --git a/shynet/core/templates/core/includes/session_list.html b/shynet/core/templates/core/includes/session_list.html new file mode 100644 index 0000000..909a6e5 --- /dev/null +++ b/shynet/core/templates/core/includes/session_list.html @@ -0,0 +1,35 @@ +{% load humanize helpers %} + + + + + + + + + + + {% for session in object_list %} + + + + + + + + {% endfor %} + +
Session StartIdentityNetworkDurationHits
+ + {{session.start_time|date:"M j Y, g:i a"|capfirst}} + {% if session.is_currently_active %} + Online + {% endif %} + + + {% if session.identifier %} + {{session.identifier}} + {% else %} + + {% endif %} + {{session.country|flag_emoji}} {{session.asn|default:"Unknown"}}{{session.duration|naturaldelta}}{{session.hit_set.count|intcomma}}
\ No newline at end of file diff --git a/shynet/core/templates/core/pages/dashboard.html b/shynet/core/templates/core/pages/dashboard.html index e301a97..7f4362f 100644 --- a/shynet/core/templates/core/pages/dashboard.html +++ b/shynet/core/templates/core/pages/dashboard.html @@ -21,6 +21,6 @@ {% for object in services %} {% include 'core/includes/service_overview.html' %} {% empty %} -

You don't have any services.

+

You don't have any services on this Shynet instance yet.

{% endfor %} {% endblock %} \ No newline at end of file diff --git a/shynet/core/templates/core/pages/service.html b/shynet/core/templates/core/pages/service.html index 707b488..74dc71e 100644 --- a/shynet/core/templates/core/pages/service.html +++ b/shynet/core/templates/core/pages/service.html @@ -178,6 +178,10 @@ -View individual sessions - → +
+ {% include 'core/includes/session_list.html' %} +
+ View more sessions + → +
{% endblock %} \ No newline at end of file diff --git a/shynet/core/templates/core/pages/service_session_list.html b/shynet/core/templates/core/pages/service_session_list.html index a38922f..a87910a 100644 --- a/shynet/core/templates/core/pages/service_session_list.html +++ b/shynet/core/templates/core/pages/service_session_list.html @@ -11,39 +11,7 @@ {% block service_content %}
- - - - - - - - - - {% for session in object_list %} - - - - - - - - {% endfor %} - -
TimeIdentityNetworkDurationHits
- - {{session.start_time|date:"M j Y, g:i a"|capfirst}} - {% if session.is_currently_active %} - Online - {% endif %} - - - {% if session.identifier %} - {{session.identifier}} - {% else %} - - {% endif %} - {{session.country|flag_emoji}} {{session.asn|default:"Unknown"}}{{session.duration|naturaldelta}}{{session.hit_set.count|intcomma}}
+ {% include 'core/includes/session_list.html' %}
{% pagination page_obj request %} {% endblock %} \ No newline at end of file diff --git a/shynet/core/templates/core/pages/service_update.html b/shynet/core/templates/core/pages/service_update.html index 6da4611..d75793d 100644 --- a/shynet/core/templates/core/pages/service_update.html +++ b/shynet/core/templates/core/pages/service_update.html @@ -11,24 +11,29 @@ {% block service_content %}
Installation
+

Place the following snippet at the end of the <body> tag on any page you'd like to track.

- {% filter force_escape %}{% endfilter %} + {% filter force_escape %} + + {% endfilter %}
+
+
Settings
+
+ {% csrf_token %} +
+ {{form|a17t}} +
+
+
+ + Cancel +
+
+ Delete +
+
+
-
-
- {% csrf_token %} -
- {{form|a17t}} -
-
-
- - Cancel -
-
- Delete -
-
-
{% endblock %} \ No newline at end of file diff --git a/shynet/core/views.py b/shynet/core/views.py index 4a142a8..8cb3b2a 100644 --- a/shynet/core/views.py +++ b/shynet/core/views.py @@ -1,9 +1,16 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.shortcuts import get_object_or_404, reverse from django.utils import timezone -from django.views.generic import (CreateView, DeleteView, DetailView, ListView, - TemplateView, UpdateView) +from django.views.generic import ( + CreateView, + DeleteView, + DetailView, + ListView, + TemplateView, + UpdateView, +) from rules.contrib.views import PermissionRequiredMixin +from django.db.models import Q from analytics.models import Session @@ -21,7 +28,9 @@ class DashboardView(LoginRequiredMixin, DateRangeMixin, TemplateView): def get_context_data(self, **kwargs): data = super().get_context_data(**kwargs) - data["services"] = Service.objects.filter(owner=self.request.user) + data["services"] = Service.objects.filter( + Q(owner=self.request.user) | Q(collaborators__in=[self.request.user]) + ) for service in data["services"]: service.stats = service.get_core_stats(data["start_date"], data["end_date"]) return data @@ -51,6 +60,11 @@ class ServiceView( def get_context_data(self, **kwargs): data = super().get_context_data(**kwargs) data["stats"] = self.object.get_core_stats(data["start_date"], data["end_date"]) + data["object_list"] = Session.objects.filter( + service=self.get_object(), + start_time__lt=self.get_end_date(), + start_time__gt=self.get_start_date(), + ).order_by("-start_time")[:10] return data @@ -92,7 +106,7 @@ class ServiceSessionsListView( service=self.get_object(), start_time__lt=self.get_end_date(), start_time__gt=self.get_start_date(), - ) + ).order_by("-start_time") def get_context_data(self, **kwargs): data = super().get_context_data(**kwargs) diff --git a/shynet/shynet/settings.py b/shynet/shynet/settings.py index f691206..9d3503d 100644 --- a/shynet/shynet/settings.py +++ b/shynet/shynet/settings.py @@ -26,9 +26,9 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SECRET_KEY = "q@@928+gjkhmcdpuwse0awn@#ygm#0etg11jlny+b*^cm5m-x!" # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = os.getenv("DEBUG", "True") == "True" -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",") # Application definition @@ -42,7 +42,7 @@ INSTALLED_APPS = [ "django.contrib.staticfiles", "django.contrib.sites", "django.contrib.humanize", - "rules", + "rules.apps.AutodiscoverRulesConfig", "a17t", "core", "analytics", @@ -168,6 +168,24 @@ MESSAGE_TAGS = { messages.SUCCESS: "~positive", } +# Email + +SERVER_EMAIL = os.getenv("SERVER_EMAIL", "Shynet ") +DEFAULT_FROM_EMAIL = SERVER_EMAIL + +if DEBUG: + EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" +else: + EMAIL_HOST = os.environ.get("EMAIL_HOST") + EMAIL_PORT = int(os.environ.get("EMAIL_PORT", 465)) + EMAIL_HOST_USER = os.environ.get("EMAIL_HOST_USER") + EMAIL_HOST_PASSWORD = os.environ.get("EMAIL_HOST_PASSWORD") + EMAIL_USE_SSL = True + # Shynet -ONLY_SUPERUSERS_CREATE = True # Can everyone create services, or only superusers? +ONLY_SUPERUSERS_CREATE = True +# Can everyone create services, or only superusers? +# Note that in the current version of Shynet, being able to edit a service allows +# you to see every registered user on the Shynet instance. This will be changed in +# a future version.