diff --git a/maraudes/views.py b/maraudes/views.py index 3c5fd27..615ddee 100644 --- a/maraudes/views.py +++ b/maraudes/views.py @@ -22,10 +22,12 @@ from .forms import ( RencontreForm, RencontreInlineFormSet, ObservationInlineFormSet, ObservationInlineFormSetNoExtra, MaraudeAutoDateForm, MonthSelectForm, ) +from utilisateurs.models import Maraudeur + from website import decorators as website webpage = website.webpage( ajax=False, - permissions=['maraudes.view_maraudes'], + app_users=[Maraudeur], app_menu=["maraudes/menu_dernieres_maraudes.html", "maraudes/menu_administration.html"] ) diff --git a/suivi/views.py b/suivi/views.py index 0af98db..7459d55 100644 --- a/suivi/views.py +++ b/suivi/views.py @@ -7,10 +7,11 @@ from .forms import * from notes.mixins import NoteFormMixin from notes.forms import AutoNoteForm # Create your views here. +from utilisateurs.models import Maraudeur from website import decorators as website webpage = website.webpage( ajax=False, - permissions=['sujets.view_sujets'], + app_users=[Maraudeur], app_menu=["suivi/menu_sujets.html"] ) diff --git a/sujets/views.py b/sujets/views.py index 3bdd258..5382885 100644 --- a/sujets/views.py +++ b/sujets/views.py @@ -5,10 +5,11 @@ from .models import Sujet from .forms import SujetCreateForm ### Webpage config +from utilisateurs.models import Maraudeur from website import decorators as website webpage = website.webpage( ajax=True, - permissions=['sujets.view_sujets'], + app_users=[Maraudeur], app_name="suivi", app_menu=[] ) @@ -70,10 +71,6 @@ class SujetCreateView(generic.edit.CreateView): class PageInfo: title = "Nouveau sujet" header = "Nouveau sujet" - # Special permissions - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.permissions += ['sujets.add_sujet'] #CreateView template_name = "sujets/sujet_create.html" form_class = SujetCreateForm diff --git a/website/backends.py b/website/backends.py index 94c676e..297fca7 100644 --- a/website/backends.py +++ b/website/backends.py @@ -1,15 +1,25 @@ from django.contrib.auth.backends import ModelBackend +from utilisateurs.models import Maraudeur class MyBackend(ModelBackend): def authenticate(self, **kwargs): - print('use MyBackend') + print('authenticate using MyBackend') return super().authenticate(**kwargs) def get_user(self, user_id): + """ Retourne la classe enfant de l'utilisateur connecté + s'il en a une, sinon le User par défaut. + """ print('use MyBackend: get_user', user_id) - return super().get_user(user_id) + try: + user = Maraudeur.objects.get(pk=user_id) + except Maraudeur.DoesNotExist: + print('no Maraudeur found. Using base user class') + user = super().get_user(user_id) + print("found:", user, user.__class__) + return user def has_perm(self, *args, **kwargs): print('call has_perm', args, kwargs) diff --git a/website/decorators.py b/website/decorators.py index 128a983..8151198 100644 --- a/website/decorators.py +++ b/website/decorators.py @@ -14,14 +14,18 @@ def webpage(**options): permissions = options.pop('permissions', []) app_menu = options.pop('app_menu', []) app_name = options.pop('app_name', None) + app_users = options.pop('app_users', []) new_bases = [] if ajax: new_bases.append(WebsiteAjaxTemplateMixin) else: new_bases.append(WebsiteTemplateMixin) + if permissions: new_bases.append(PermissionRequiredMixin) + if app_users: + new_bases.append(SpecialUserRequiredMixin) def class_decorator(cls): _insert_bases(cls, new_bases) @@ -29,6 +33,7 @@ def webpage(**options): cls.permissions = permissions cls.app_menu = app_menu.copy() #avoid conflict between Views cls.app_name = app_name + cls.app_users = app_users.copy() return cls return class_decorator diff --git a/website/mixins.py b/website/mixins.py index 5e3e95e..ada0136 100644 --- a/website/mixins.py +++ b/website/mixins.py @@ -2,7 +2,9 @@ import datetime from django.utils import timezone from django.core.exceptions import ImproperlyConfigured from django.apps import apps +#TODO: remove next line from django.contrib.auth.decorators import login_required, permission_required +from django.contrib.auth.decorators import user_passes_test from django.template import Template, Context from django.views.generic.base import ContextMixin, TemplateResponseMixin @@ -17,6 +19,28 @@ class PermissionRequiredMixin(object): view = super(PermissionRequiredMixin, cls).as_view(**initkwargs) return permission_required(cls.permissions)(view) +def special_user_required(authorized_users): + + valid_cls = tuple(authorized_users) + + def check_special_user(user): + print('check user is instance of', valid_cls) + if isinstance(user, valid_cls): + return True + else: + return False + + return user_passes_test(check_special_user) + + +class SpecialUserRequiredMixin(object): + app_users = [] + + @classmethod + def as_view(cls, **initkwargs): + view = super().as_view(**initkwargs) + return special_user_required(cls.app_users)(view) + class TemplateFieldsMetaclass(type): @@ -105,10 +129,13 @@ class WebsiteTemplateMixin(TemplateResponseMixin): def get_active_app(self): if not self.app_name: self.app_name = self.__class__.__module__.split(".")[0] + # If app is website, there is no "active" application + if self.app_name == "website": + return None + active_app = apps.get_app_config(self.app_name) if not active_app in self.apps: #TODO: how do we deal with this ? - print("%s must be registered in Configuration.navbar_apps" % active_app) - return None + raise ValueError("%s must be registered in Configuration.navbar_apps" % active_app) return active_app @property diff --git a/website/templates/navbar.html b/website/templates/navbar.html index 4423d1a..fada0f9 100644 --- a/website/templates/navbar.html +++ b/website/templates/navbar.html @@ -15,7 +15,7 @@