diff --git a/README.rst b/README.rst index 664d44feccd825af419d30650fa31a27e97234c2..067f83e32bfedf6251c91b5d5e42162c1db97b9e 100644 --- a/README.rst +++ b/README.rst @@ -36,6 +36,7 @@ Licence :: + Copyright © 2021 magicfelix <felix@felix-zauberer.de> Copyright © 2017, 2018, 2019, 2020 Jonathan Weth <wethjo@katharineum.de> Copyright © 2017, 2018, 2019 Frank Poetzsch-Heffter <p-h@katharineum.de> Copyright © 2018, 2019, 2020 Julian Leucker <leuckeju@katharineum.de> diff --git a/aleksis/core/apps.py b/aleksis/core/apps.py index 42edc4bceaa61a55de310f59cea74dc270a3cf0b..a3b9b7a9a3957b9af7ad0b9ddeb57d00a630ca73 100644 --- a/aleksis/core/apps.py +++ b/aleksis/core/apps.py @@ -28,6 +28,7 @@ class CoreConfig(AppConfig): } licence = "EUPL-1.2+" copyright_info = ( + ([2021], "magicfelix", "felix@felix-zauberer.de"), ([2017, 2018, 2019, 2020], "Jonathan Weth", "wethjo@katharineum.de"), ([2017, 2018, 2019], "Frank Poetzsch-Heffter", "p-h@katharineum.de"), ([2018, 2019, 2020], "Julian Leucker", "leuckeju@katharineum.de"), diff --git a/aleksis/core/preferences.py b/aleksis/core/preferences.py index ad90929ef8f4332daf50ef3485b47383f79a9dea..9c81cf4c82fe573ba8787d309b0d4bbfba1751ff 100644 --- a/aleksis/core/preferences.py +++ b/aleksis/core/preferences.py @@ -252,3 +252,12 @@ class DataChecksEmailsRecipientGroups(ModelMultipleChoicePreference): default = [] model = Group verbose_name = _("Email recipient groups for data checks problem emails") + + +@site_preferences_registry.register +class AnonymousDashboard(BooleanPreference): + section = general + name = "anonymous_dashboard" + default = False + required = False + verbose_name = _("Show dashboard to users without login") diff --git a/aleksis/core/rules.py b/aleksis/core/rules.py index 5e39c1af4d38f15985c4ac13e6348a3130702391..cf29b8790a310573d4719f89230a200850ea9bc8 100644 --- a/aleksis/core/rules.py +++ b/aleksis/core/rules.py @@ -9,12 +9,14 @@ from .util.predicates import ( is_current_person, is_group_owner, is_notification_recipient, + is_site_preference_set, ) rules.add_perm("core", rules.always_allow) # View dashboard -rules.add_perm("core.view_dashboard", has_person) +view_dashboard_predicate = is_site_preference_set("general", "anonymous_dashboard") | has_person +rules.add_perm("core.view_dashboard", view_dashboard_predicate) # View notifications rules.add_perm("core.view_notifications", has_person) @@ -310,6 +312,9 @@ rules.add_perm("core.edit_dashboardwidget", edit_dashboard_widget_predicate) delete_dashboard_widget_predicate = has_person & has_global_perm("core.delete_dashboardwidget") rules.add_perm("core.delete_dashboardwidget", delete_dashboard_widget_predicate) +edit_dashboard_predicate = has_person +rules.add_perm("core.edit_dashboard", edit_dashboard_predicate) + edit_default_dashboard_predicate = has_person & has_global_perm("core.edit_default_dashboard") rules.add_perm("core.edit_default_dashboard", edit_default_dashboard_predicate) diff --git a/aleksis/core/templates/core/index.html b/aleksis/core/templates/core/index.html index 419bb59f11b5084eee7ac379605c3cefe00d530b..b690155f010e932cdb35e80eac639e18fc38bd27 100644 --- a/aleksis/core/templates/core/index.html +++ b/aleksis/core/templates/core/index.html @@ -1,5 +1,5 @@ {% extends 'core/base.html' %} -{% load i18n static dashboard %} +{% load i18n static dashboard rules %} {% block browser_title %}{% blocktrans %}Home{% endblocktrans %}{% endblock %} {% block no_page_title %}{% endblock %} @@ -9,51 +9,54 @@ {% endblock %} {% block content %} - <a class="btn-flat waves-effect waves-light right" href="{% url "edit_dashboard" %}"> - <i class="material-icons left">edit</i> - {% trans "Edit dashboard" %} - </a> + {% has_perm "core.edit_dashboard" user as can_edit_dashboard %} + {% if can_edit_dashboard %} + <a class="btn-flat waves-effect waves-light right" href="{% url "edit_dashboard" %}"> + <i class="material-icons left">edit</i> + {% trans "Edit dashboard" %} + </a> + {% endif %} <h4> {{ request.site.preferences.general__title }} </h4> - {% if user.is_authenticated %} - {% for notification in unread_notifications %} - <div class="alert primary scale-transition"> - <div> - <i class="material-icons left">info</i> - - <div class="right"> - <a class="btn-flat waves-effect" href="{% url "notification_mark_read" notification.id %}"> - <i class="material-icons center">close</i> - </a> - </div> + {% for notification in unread_notifications %} + <div class="alert primary scale-transition"> + <div> + <i class="material-icons left">info</i> - <strong>{{ notification.title }}</strong> - <p>{{ notification.description }}</p> + <div class="right"> + <a class="btn-flat waves-effect" href="{% url "notification_mark_read" notification.id %}"> + <i class="material-icons center">close</i> + </a> </div> - </div> - {% endfor %} - - {% include "core/partials/announcements.html" with announcements=announcements %} - <div class="row" id="live_load"> - {% for widget in widgets %} - <div class="col s{{ widget.size_s }} m{{ widget.size_m }} l{{ widget.size_l }} xl{{ widget.size_xl }}"> - {% include_widget widget %} - </div> - {% endfor %} + <strong>{{ notification.title }}</strong> + <p>{{ notification.description }}</p> + </div> </div> + {% endfor %} + + {% include "core/partials/announcements.html" with announcements=announcements %} - {% if default_dashboard and widgets %} - <div class="grey-text right"> - {% blocktrans %} - You didn't customise your dashboard so that you see the system default. Please click on "Edit dashboard" to - customise your personal dashboard. - {% endblocktrans %} + <div class="row" id="live_load"> + {% for widget in widgets %} + <div class="col s{{ widget.size_s }} m{{ widget.size_m }} l{{ widget.size_l }} xl{{ widget.size_xl }}"> + {% include_widget widget %} </div> - {% endif %} + {% endfor %} + </div> + + {% if default_dashboard and widgets and can_edit_dashboard %} + <div class="grey-text right"> + {% blocktrans %} + You didn't customise your dashboard so that you see the system default. Please click on "Edit dashboard" to + customise your personal dashboard. + {% endblocktrans %} + </div> + {% endif %} + {% if activities or notifications %} <div class="row"> <div class="col s12 m6"> <h5>{% blocktrans %}Last activities{% endblocktrans %}</h5> diff --git a/aleksis/core/views.py b/aleksis/core/views.py index f1bc04013f92ed2bbde449c47cf44473be70ece0..2ee83523ca49c5b112579a98b49147dbf3afcff8 100644 --- a/aleksis/core/views.py +++ b/aleksis/core/views.py @@ -54,6 +54,7 @@ from .models import ( DashboardWidget, DashboardWidgetOrder, DataCheckResult, + DummyPerson, Group, GroupType, Notification, @@ -75,7 +76,7 @@ from .tables import ( ) from .util import messages from .util.apps import AppConfig -from .util.core_helpers import objectgetter_optional +from .util.core_helpers import has_person, objectgetter_optional from .util.forms import PreferenceLayout @@ -84,19 +85,24 @@ def index(request: HttpRequest) -> HttpResponse: """View for dashboard.""" context = {} - activities = request.user.person.activities.all()[:5] - notifications = request.user.person.notifications.all()[:5] - unread_notifications = request.user.person.notifications.all().filter(read=False) + if has_person(request.user): + person = request.user.person + widgets = person.dashboard_widgets + else: + person = DummyPerson() + widgets = [] + + activities = person.activities.all()[:5] + notifications = person.notifications.all()[:5] + unread_notifications = person.notifications.all().filter(read=False) context["activities"] = activities context["notifications"] = notifications context["unread_notifications"] = unread_notifications - announcements = Announcement.objects.at_time().for_person(request.user.person) + announcements = Announcement.objects.at_time().for_person(person) context["announcements"] = announcements - widgets = request.user.person.dashboard_widgets - if len(widgets) == 0: # Use default dashboard if there are no widgets widgets = DashboardWidgetOrder.default_dashboard_widgets @@ -859,9 +865,11 @@ class DashboardWidgetDeleteView(PermissionRequiredMixin, AdvancedDeleteView): success_message = _("The dashboard widget has been deleted.") -class EditDashboardView(View): +class EditDashboardView(PermissionRequiredMixin, View): """View for editing dashboard widget order.""" + permission_required = "core.edit_dashboard" + def get_context_data(self, request, **kwargs): context = {} self.default_dashboard = kwargs.get("default", False)