diff --git a/modoboa/core/constants.py b/modoboa/core/constants.py index f9a27a871..4130866ed 100644 --- a/modoboa/core/constants.py +++ b/modoboa/core/constants.py @@ -2,6 +2,11 @@ """Core application constants.""" +ADMIN_GROUPS = [ + "SuperAdmins", + "Resellers", + "DomainAdmins", +] LANGUAGES = ( ("cs", u"čeština"), diff --git a/modoboa/core/models.py b/modoboa/core/models.py index a7bac652e..870be90c9 100644 --- a/modoboa/core/models.py +++ b/modoboa/core/models.py @@ -6,6 +6,7 @@ from django.core.urlresolvers import reverse from django.db import models from django.utils import timezone from django.utils.encoding import python_2_unicode_compatible, smart_text +from django.utils.functional import cached_property from django.utils.translation import ugettext as _, ugettext_lazy from django.contrib.auth.hashers import make_password, is_password_usable @@ -321,14 +322,13 @@ class User(PermissionsMixin): def role(self): """Return user role.""" if not hasattr(self, "_role"): - self._role = None - if self._role is None: if self.is_superuser: self._role = "SuperAdmins" - try: - self._role = self.groups.all()[0].name - except IndexError: - self._role = "---" + else: + try: + self._role = self.groups.all()[0].name + except IndexError: + self._role = "---" return self._role @role.setter @@ -357,6 +357,11 @@ class User(PermissionsMixin): self.save() self._role = role + @cached_property + def is_admin(self): + """Shortcut to check if user is administrator.""" + return self.role in constants.ADMIN_GROUPS + def post_create(self, creator): """Grant permission on this user to creator.""" from modoboa.lib.permissions import grant_access_to_object diff --git a/modoboa/core/templates/core/dashboard.html b/modoboa/core/templates/core/dashboard.html new file mode 100644 index 000000000..24a87524e --- /dev/null +++ b/modoboa/core/templates/core/dashboard.html @@ -0,0 +1,40 @@ +{% extends "fluid.html" %} + +{% load i18n %} + +{% block container_content %} + +
+
+

{% blocktrans with user=user trimmed %}Hello {{ user }}.{% endblocktrans %}

+ +
+
+
+
+

{% trans "Latest news" %}

+
+ + + {% for post in news %} + + + + + {% endfor %} + +
{{ post.title }}{{ post.published|date:"DATE_FORMAT" }}
+ +
+ {% blocktrans trimmed %} + Visit to the official weblog for more information. + {% endblocktrans %} +
+
+
+
+ +
+
+ +{% endblock container_content %} diff --git a/modoboa/core/templatetags/core_tags.py b/modoboa/core/templatetags/core_tags.py index b1ef9afc5..1f508ab7d 100644 --- a/modoboa/core/templatetags/core_tags.py +++ b/modoboa/core/templatetags/core_tags.py @@ -18,8 +18,17 @@ register = template.Library() @register.simple_tag def core_menu(selection, user): - entries = \ - events.raiseQueryEvent("AdminMenuDisplay", "top_menu", user) + """Build the top level menu.""" + entries = [] + if user.is_admin: + entries += [ + {"name": "dashboard", + "label": "", + "img": "fa fa-home fa-lg", + "url": reverse("core:dashboard")} + ] + entries += ( + events.raiseQueryEvent("AdminMenuDisplay", "top_menu", user)) if user.is_superuser: entries += [ {"name": "settings", diff --git a/modoboa/core/urls.py b/modoboa/core/urls.py index 61c56ceca..f63023f8d 100644 --- a/modoboa/core/urls.py +++ b/modoboa/core/urls.py @@ -1,9 +1,13 @@ from django.conf.urls import patterns, url +from . import views urlpatterns = patterns( '', + url(r'^dashboard/$', views.DashboardView.as_view(), + name="dashboard"), + url(r'^accounts/login/$', 'modoboa.core.views.auth.dologin', name="login"), url(r'^accounts/logout/$', 'modoboa.core.views.auth.dologout', diff --git a/modoboa/core/views/__init__.py b/modoboa/core/views/__init__.py index e69de29bb..b4d482849 100644 --- a/modoboa/core/views/__init__.py +++ b/modoboa/core/views/__init__.py @@ -0,0 +1,7 @@ +"""Core views.""" + +from .dashboard import DashboardView + +__all__ = [ + "DashboardView", +] diff --git a/modoboa/core/views/auth.py b/modoboa/core/views/auth.py index ad115044f..f56e8ebf7 100644 --- a/modoboa/core/views/auth.py +++ b/modoboa/core/views/auth.py @@ -12,6 +12,8 @@ from modoboa.core.forms import LoginForm from modoboa.lib import events from modoboa.lib.web_utils import _render_to_string +logger = logging.getLogger("modoboa.auth") + def dologin(request): """Try to authenticate.""" @@ -45,10 +47,7 @@ def dologin(request): if nextlocation is None: nextlocation = request.POST.get("next", None) if nextlocation is None or nextlocation == "None": - if user.group == "SimpleUsers": - nextlocation = reverse("topredirection") - else: - nextlocation = reverse("admin:domain_list") + nextlocation = reverse("topredirection") return HttpResponseRedirect(nextlocation) error = _( "Your username and password didn't match. Please try again.") diff --git a/modoboa/core/views/dashboard.py b/modoboa/core/views/dashboard.py new file mode 100644 index 000000000..a375a65c5 --- /dev/null +++ b/modoboa/core/views/dashboard.py @@ -0,0 +1,37 @@ +"""Core dashboard views.""" + +from dateutil import parser +import feedparser + +from django.views import generic + +from django.contrib.auth import mixins as auth_mixins + + +class DashboardView(auth_mixins.AccessMixin, generic.TemplateView): + """Dashboard view.""" + + template_name = "core/dashboard.html" + + def dispatch(self, request, *args, **kwargs): + """Check if user can access dashboard.""" + if not request.user.is_admin: + return self.handle_no_permission() + return super(DashboardView, self).dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + """Add context variables.""" + context = super(DashboardView, self).get_context_data(**kwargs) + context.update({"selection": "dashboard"}) + if self.request.user.language == "fr": + lang = "fr" + else: + lang = "en" + posts = feedparser.parse( + "https://modoboa.org/{}/weblog/feeds/".format(lang)) + entries = [] + for entry in posts["entries"][:5]: + entry["published"] = parser.parse(entry["published"]) + entries.append(entry) + context.update({"news": entries}) + return context diff --git a/modoboa/lib/web_utils.py b/modoboa/lib/web_utils.py index eb06c157d..a436c8ac2 100644 --- a/modoboa/lib/web_utils.py +++ b/modoboa/lib/web_utils.py @@ -154,7 +154,7 @@ def topredirection(request): from modoboa.lib import parameters from modoboa.core.extensions import exts_pool - if request.user.group == 'SimpleUsers': + if request.user.role == "SimpleUsers": topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="core") if topredir != "user": infos = exts_pool.get_extension_infos(topredir) @@ -162,8 +162,7 @@ def topredirection(request): else: path = reverse("core:user_index") else: - # FIXME - path = reverse("admin:domain_list") + path = reverse("core:dashboard") return HttpResponseRedirect(path) diff --git a/requirements.txt b/requirements.txt index bb39671ba..c11bde24b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,3 +19,5 @@ gevent==1.1.1 ipaddress dnspython==1.12.0 jsonfield==1.0.3 +py-dateutil==2.2 +feedparser==5.2.1