diff --git a/accounting/api.py b/accounting/api.py index a16fb7ab..5ba6c12d 100644 --- a/accounting/api.py +++ b/accounting/api.py @@ -7,7 +7,7 @@ from ninja_extra.schemas import PaginatedResponseSchema from accounting.models import ClubAccount, Company from accounting.schemas import ClubAccountSchema, CompanySchema -from core.api_permissions import CanAccessLookup +from core.auth.api_permissions import CanAccessLookup @api_controller("/lookup", permissions=[CanAccessLookup]) diff --git a/accounting/views.py b/accounting/views.py index dd5d2e09..d379b60d 100644 --- a/accounting/views.py +++ b/accounting/views.py @@ -44,8 +44,13 @@ from accounting.widgets.select import ( ) from club.models import Club from club.widgets.select import AutoCompleteSelectClub +from core.auth.mixins import ( + CanCreateMixin, + CanEditMixin, + CanEditPropMixin, + CanViewMixin, +) from core.models import User -from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import SelectDate, SelectFile from core.views.mixins import TabedViewMixin from core.views.widgets.select import AutoCompleteSelectUser diff --git a/club/api.py b/club/api.py index 9a680154..2ad0f5c8 100644 --- a/club/api.py +++ b/club/api.py @@ -7,7 +7,7 @@ from ninja_extra.schemas import PaginatedResponseSchema from club.models import Club from club.schemas import ClubSchema -from core.api_permissions import CanAccessLookup +from core.auth.api_permissions import CanAccessLookup @api_controller("/club") diff --git a/club/views.py b/club/views.py index a6b6d009..498e16e1 100644 --- a/club/views.py +++ b/club/views.py @@ -50,15 +50,14 @@ from com.views import ( PosterEditBaseView, PosterListBaseView, ) -from core.models import PageRev -from core.views import ( +from core.auth.mixins import ( CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin, - DetailFormView, - PageEditViewBase, ) +from core.models import PageRev +from core.views import DetailFormView, PageEditViewBase from core.views.mixins import TabedViewMixin from counter.models import Selling diff --git a/com/views.py b/com/views.py index 9216cb00..179c2bed 100644 --- a/com/views.py +++ b/com/views.py @@ -44,8 +44,8 @@ from club.models import Club, Mailing from com.calendar import IcsCalendar from com.forms import NewsDateForm, NewsForm, PosterForm from com.models import News, NewsDate, Poster, Screen, Sith, Weekmail, WeekmailArticle +from core.auth.mixins import CanEditPropMixin, CanViewMixin from core.models import User -from core.views import CanEditPropMixin, CanViewMixin, QuickNotifMixin, TabedViewMixin from core.views.mixins import QuickNotifMixin, TabedViewMixin from core.views.widgets.markdown import MarkdownInput diff --git a/core/api.py b/core/api.py index 1662cb84..e1b3bbbd 100644 --- a/core/api.py +++ b/core/api.py @@ -11,10 +11,7 @@ from ninja_extra.pagination import PageNumberPaginationExtra from ninja_extra.schemas import PaginatedResponseSchema from club.models import Mailing -from core.api_permissions import ( - CanAccessLookup, - CanView, -) +from core.auth.api_permissions import CanAccessLookup, CanView from core.models import Group, SithFile, User from core.schemas import ( FamilyGodfatherSchema, diff --git a/core/auth/__init__.py b/core/auth/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/core/api_permissions.py b/core/auth/api_permissions.py similarity index 100% rename from core/api_permissions.py rename to core/auth/api_permissions.py diff --git a/core/auth_backends.py b/core/auth/backends.py similarity index 100% rename from core/auth_backends.py rename to core/auth/backends.py diff --git a/core/auth/mixins.py b/core/auth/mixins.py new file mode 100644 index 00000000..b25397b0 --- /dev/null +++ b/core/auth/mixins.py @@ -0,0 +1,212 @@ +# +# Copyright 2016,2017 +# - Skia +# - Sli +# +# Ce fichier fait partie du site de l'Association des Étudiants de l'UTBM, +# http://ae.utbm.fr. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License a published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Sofware Foundation, Inc., 59 Temple +# Place - Suite 330, Boston, MA 02111-1307, USA. +# +# + +import types +from typing import Any + +from django.contrib.auth.mixins import AccessMixin +from django.core.exceptions import PermissionDenied +from django.views.generic.base import View + +from core.models import User + + +def can_edit_prop(obj: Any, user: User) -> bool: + """Can the user edit the properties of the object. + + Args: + obj: Object to test for permission + user: core.models.User to test permissions against + + Returns: + True if user is authorized to edit object properties else False + + Examples: + ```python + if not can_edit_prop(self.object ,request.user): + raise PermissionDenied + ``` + """ + return obj is None or user.is_owner(obj) + + +def can_edit(obj: Any, user: User) -> bool: + """Can the user edit the object. + + Args: + obj: Object to test for permission + user: core.models.User to test permissions against + + Returns: + True if user is authorized to edit object else False + + Examples: + ```python + if not can_edit(self.object, request.user): + raise PermissionDenied + ``` + """ + if obj is None or user.can_edit(obj): + return True + return can_edit_prop(obj, user) + + +def can_view(obj: Any, user: User) -> bool: + """Can the user see the object. + + Args: + obj: Object to test for permission + user: core.models.User to test permissions against + + Returns: + True if user is authorized to see object else False + + Examples: + ```python + if not can_view(self.object ,request.user): + raise PermissionDenied + ``` + """ + if obj is None or user.can_view(obj): + return True + return can_edit(obj, user) + + +class GenericContentPermissionMixinBuilder(View): + """Used to build permission mixins. + + This view protect any child view that would be showing an object that is restricted based + on two properties. + + Attributes: + raised_error: permission to be raised + """ + + raised_error = PermissionDenied + + @staticmethod + def permission_function(obj: Any, user: User) -> bool: + """Function to test permission with.""" + return False + + @classmethod + def get_permission_function(cls, obj, user): + return cls.permission_function(obj, user) + + def dispatch(self, request, *arg, **kwargs): + if hasattr(self, "get_object") and callable(self.get_object): + self.object = self.get_object() + if not self.get_permission_function(self.object, request.user): + raise self.raised_error + return super().dispatch(request, *arg, **kwargs) + + # If we get here, it's a ListView + + queryset = self.get_queryset() + l_id = [o.id for o in queryset if self.get_permission_function(o, request.user)] + if not l_id and queryset.count() != 0: + raise self.raised_error + self._get_queryset = self.get_queryset + + def get_qs(self2): + return self2._get_queryset().filter(id__in=l_id) + + self.get_queryset = types.MethodType(get_qs, self) + return super().dispatch(request, *arg, **kwargs) + + +class CanCreateMixin(View): + """Protect any child view that would create an object. + + Raises: + PermissionDenied: + If the user has not the necessary permission + to create the object of the view. + """ + + def dispatch(self, request, *arg, **kwargs): + res = super().dispatch(request, *arg, **kwargs) + if not request.user.is_authenticated: + raise PermissionDenied + return res + + def form_valid(self, form): + obj = form.instance + if can_edit_prop(obj, self.request.user): + return super().form_valid(form) + raise PermissionDenied + + +class CanEditPropMixin(GenericContentPermissionMixinBuilder): + """Ensure the user has owner permissions on the child view object. + + In other word, you can make a view with this view as parent, + and it will be retricted to the users that are in the + object's owner_group or that pass the `obj.can_be_viewed_by` test. + + Raises: + PermissionDenied: If the user cannot see the object + """ + + permission_function = can_edit_prop + + +class CanEditMixin(GenericContentPermissionMixinBuilder): + """Ensure the user has permission to edit this view's object. + + Raises: + PermissionDenied: if the user cannot edit this view's object. + """ + + permission_function = can_edit + + +class CanViewMixin(GenericContentPermissionMixinBuilder): + """Ensure the user has permission to view this view's object. + + Raises: + PermissionDenied: if the user cannot edit this view's object. + """ + + permission_function = can_view + + +class FormerSubscriberMixin(AccessMixin): + """Check if the user was at least an old subscriber. + + Raises: + PermissionDenied: if the user never subscribed. + """ + + def dispatch(self, request, *args, **kwargs): + if not request.user.was_subscribed: + raise PermissionDenied + return super().dispatch(request, *args, **kwargs) + + +class SubscriberMixin(AccessMixin): + def dispatch(self, request, *args, **kwargs): + if not request.user.is_subscribed: + return self.handle_no_permission() + return super().dispatch(request, *args, **kwargs) diff --git a/core/views/__init__.py b/core/views/__init__.py index 0cff8afe..c8152f78 100644 --- a/core/views/__init__.py +++ b/core/views/__init__.py @@ -22,23 +22,17 @@ # # -import types -from typing import Any - -from django.contrib.auth.mixins import AccessMixin -from django.core.exceptions import PermissionDenied from django.http import ( HttpResponseForbidden, HttpResponseNotFound, HttpResponseServerError, ) +from django.shortcuts import render from django.utils.functional import cached_property -from django.views.generic.base import View from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import FormView from sentry_sdk import last_event_id -from core.models import User from core.views.forms import LoginForm @@ -60,186 +54,6 @@ def internal_servor_error(request): return HttpResponseServerError(render(request, "core/500.jinja")) -def can_edit_prop(obj: Any, user: User) -> bool: - """Can the user edit the properties of the object. - - Args: - obj: Object to test for permission - user: core.models.User to test permissions against - - Returns: - True if user is authorized to edit object properties else False - - Examples: - ```python - if not can_edit_prop(self.object ,request.user): - raise PermissionDenied - ``` - """ - return obj is None or user.is_owner(obj) - - -def can_edit(obj: Any, user: User) -> bool: - """Can the user edit the object. - - Args: - obj: Object to test for permission - user: core.models.User to test permissions against - - Returns: - True if user is authorized to edit object else False - - Examples: - ```python - if not can_edit(self.object, request.user): - raise PermissionDenied - ``` - """ - if obj is None or user.can_edit(obj): - return True - return can_edit_prop(obj, user) - - -def can_view(obj: Any, user: User) -> bool: - """Can the user see the object. - - Args: - obj: Object to test for permission - user: core.models.User to test permissions against - - Returns: - True if user is authorized to see object else False - - Examples: - ```python - if not can_view(self.object ,request.user): - raise PermissionDenied - ``` - """ - if obj is None or user.can_view(obj): - return True - return can_edit(obj, user) - - -class GenericContentPermissionMixinBuilder(View): - """Used to build permission mixins. - - This view protect any child view that would be showing an object that is restricted based - on two properties. - - Attributes: - raised_error: permission to be raised - """ - - raised_error = PermissionDenied - - @staticmethod - def permission_function(obj: Any, user: User) -> bool: - """Function to test permission with.""" - return False - - @classmethod - def get_permission_function(cls, obj, user): - return cls.permission_function(obj, user) - - def dispatch(self, request, *arg, **kwargs): - if hasattr(self, "get_object") and callable(self.get_object): - self.object = self.get_object() - if not self.get_permission_function(self.object, request.user): - raise self.raised_error - return super().dispatch(request, *arg, **kwargs) - - # If we get here, it's a ListView - - queryset = self.get_queryset() - l_id = [o.id for o in queryset if self.get_permission_function(o, request.user)] - if not l_id and queryset.count() != 0: - raise self.raised_error - self._get_queryset = self.get_queryset - - def get_qs(self2): - return self2._get_queryset().filter(id__in=l_id) - - self.get_queryset = types.MethodType(get_qs, self) - return super().dispatch(request, *arg, **kwargs) - - -class CanCreateMixin(View): - """Protect any child view that would create an object. - - Raises: - PermissionDenied: - If the user has not the necessary permission - to create the object of the view. - """ - - def dispatch(self, request, *arg, **kwargs): - res = super().dispatch(request, *arg, **kwargs) - if not request.user.is_authenticated: - raise PermissionDenied - return res - - def form_valid(self, form): - obj = form.instance - if can_edit_prop(obj, self.request.user): - return super().form_valid(form) - raise PermissionDenied - - -class CanEditPropMixin(GenericContentPermissionMixinBuilder): - """Ensure the user has owner permissions on the child view object. - - In other word, you can make a view with this view as parent, - and it will be retricted to the users that are in the - object's owner_group or that pass the `obj.can_be_viewed_by` test. - - Raises: - PermissionDenied: If the user cannot see the object - """ - - permission_function = can_edit_prop - - -class CanEditMixin(GenericContentPermissionMixinBuilder): - """Ensure the user has permission to edit this view's object. - - Raises: - PermissionDenied: if the user cannot edit this view's object. - """ - - permission_function = can_edit - - -class CanViewMixin(GenericContentPermissionMixinBuilder): - """Ensure the user has permission to view this view's object. - - Raises: - PermissionDenied: if the user cannot edit this view's object. - """ - - permission_function = can_view - - -class FormerSubscriberMixin(AccessMixin): - """Check if the user was at least an old subscriber. - - Raises: - PermissionDenied: if the user never subscribed. - """ - - def dispatch(self, request, *args, **kwargs): - if not request.user.was_subscribed: - raise PermissionDenied - return super().dispatch(request, *args, **kwargs) - - -class SubscriberMixin(AccessMixin): - def dispatch(self, request, *args, **kwargs): - if not request.user.is_subscribed: - return self.handle_no_permission() - return super().dispatch(request, *args, **kwargs) - - class DetailFormView(SingleObjectMixin, FormView): """Class that allow both a detail view and a form view.""" diff --git a/core/views/files.py b/core/views/files.py index e2ccaa6b..04498d5c 100644 --- a/core/views/files.py +++ b/core/views/files.py @@ -33,13 +33,13 @@ from django.views.generic import DetailView, ListView from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import DeleteView, FormMixin, UpdateView -from core.models import Notification, SithFile, User -from core.views import ( +from core.auth.mixins import ( CanEditMixin, CanEditPropMixin, CanViewMixin, can_view, ) +from core.models import Notification, SithFile, User from core.views.mixins import AllowFragment from core.views.widgets.select import ( AutoCompleteSelectMultipleGroup, diff --git a/core/views/group.py b/core/views/group.py index 978fe686..afd6874d 100644 --- a/core/views/group.py +++ b/core/views/group.py @@ -21,8 +21,9 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import ListView from django.views.generic.edit import CreateView, DeleteView, UpdateView +from core.auth.mixins import CanCreateMixin, CanEditMixin from core.models import Group, User -from core.views import CanCreateMixin, CanEditMixin, DetailFormView +from core.views import DetailFormView from core.views.widgets.select import AutoCompleteSelectMultipleUser # Forms diff --git a/core/views/page.py b/core/views/page.py index 51a0e1a5..f4b04f9c 100644 --- a/core/views/page.py +++ b/core/views/page.py @@ -21,8 +21,13 @@ from django.urls import reverse_lazy from django.views.generic import DetailView, ListView from django.views.generic.edit import CreateView, DeleteView, UpdateView +from core.auth.mixins import ( + CanCreateMixin, + CanEditMixin, + CanEditPropMixin, + CanViewMixin, +) from core.models import LockError, Page, PageRev -from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import PageForm, PagePropForm from core.views.widgets.markdown import MarkdownInput diff --git a/core/views/user.py b/core/views/user.py index 38966900..5647d720 100644 --- a/core/views/user.py +++ b/core/views/user.py @@ -54,8 +54,8 @@ from django.views.generic.dates import MonthMixin, YearMixin from django.views.generic.edit import FormView, UpdateView from honeypot.decorators import check_honeypot +from core.auth.mixins import CanEditMixin, CanEditPropMixin, CanViewMixin from core.models import Gift, Preferences, User -from core.views import CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import ( GiftForm, LoginForm, diff --git a/counter/api.py b/counter/api.py index dd7b75f0..44b58488 100644 --- a/counter/api.py +++ b/counter/api.py @@ -20,7 +20,7 @@ from ninja_extra import ControllerBase, api_controller, paginate, route from ninja_extra.pagination import PageNumberPaginationExtra from ninja_extra.schemas import PaginatedResponseSchema -from core.api_permissions import CanAccessLookup, CanView, IsInGroup, IsRoot +from core.auth.api_permissions import CanAccessLookup, CanView, IsInGroup, IsRoot from counter.models import Counter, Product, ProductType from counter.schemas import ( CounterFilterSchema, diff --git a/counter/views/admin.py b/counter/views/admin.py index ab46581b..ffe81ea0 100644 --- a/counter/views/admin.py +++ b/counter/views/admin.py @@ -24,8 +24,8 @@ from django.utils import timezone from django.views.generic import DetailView, ListView, TemplateView from django.views.generic.edit import CreateView, DeleteView, UpdateView +from core.auth.mixins import CanEditMixin, CanViewMixin from core.utils import get_semester_code, get_start_of_semester -from core.views import CanEditMixin, CanViewMixin from counter.forms import CounterEditForm, ProductEditForm from counter.models import Counter, Product, ProductType, Refilling, Selling from counter.utils import is_logged_in_counter diff --git a/counter/views/cash.py b/counter/views/cash.py index d4a03af1..711f6864 100644 --- a/counter/views/cash.py +++ b/counter/views/cash.py @@ -23,7 +23,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from django.views.generic.edit import UpdateView -from core.views import CanViewMixin +from core.auth.mixins import CanViewMixin from counter.forms import CashSummaryFormBase from counter.models import ( CashRegisterSummary, diff --git a/counter/views/click.py b/counter/views/click.py index c1815dec..4a1e1c88 100644 --- a/counter/views/click.py +++ b/counter/views/click.py @@ -31,9 +31,9 @@ from django.views.generic import FormView from django.views.generic.detail import SingleObjectMixin from ninja.main import HttpRequest +from core.auth.mixins import CanViewMixin from core.models import User from core.utils import FormFragmentTemplateData -from core.views import CanViewMixin from counter.forms import RefillForm from counter.models import Counter, Customer, Product, Selling from counter.utils import is_logged_in_counter diff --git a/counter/views/eticket.py b/counter/views/eticket.py index a05020d6..c5b4b872 100644 --- a/counter/views/eticket.py +++ b/counter/views/eticket.py @@ -18,7 +18,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from django.views.generic.edit import CreateView, UpdateView -from core.views import CanViewMixin +from core.auth.mixins import CanViewMixin from counter.forms import EticketForm from counter.models import Eticket, Selling from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin diff --git a/counter/views/home.py b/counter/views/home.py index d66b0969..0f0cd6dd 100644 --- a/counter/views/home.py +++ b/counter/views/home.py @@ -22,7 +22,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView from django.views.generic.edit import FormMixin, ProcessFormView -from core.views import CanViewMixin +from core.auth.mixins import CanViewMixin from core.views.forms import LoginForm from counter.forms import GetUserForm from counter.models import Counter diff --git a/counter/views/student_card.py b/counter/views/student_card.py index f916260b..6e2a3358 100644 --- a/counter/views/student_card.py +++ b/counter/views/student_card.py @@ -21,8 +21,8 @@ from django.urls import reverse from django.utils.translation import gettext as _ from django.views.generic.edit import DeleteView, FormView +from core.auth.mixins import can_edit from core.utils import FormFragmentTemplateData -from core.views import can_edit from counter.forms import StudentCardForm from counter.models import Customer, StudentCard from counter.utils import is_logged_in_counter diff --git a/docs/reference/core/api_permissions.md b/docs/reference/core/api_permissions.md index 2d693fca..4ab3a2e0 100644 --- a/docs/reference/core/api_permissions.md +++ b/docs/reference/core/api_permissions.md @@ -1 +1 @@ -::: core.api_permissions \ No newline at end of file +::: core.auth.api_permissions \ No newline at end of file diff --git a/election/views.py b/election/views.py index 422205fd..1b5439f3 100644 --- a/election/views.py +++ b/election/views.py @@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView -from core.views import CanCreateMixin, CanEditMixin, CanViewMixin +from core.auth.mixins import CanCreateMixin, CanEditMixin, CanViewMixin from core.views.forms import SelectDateTime from core.views.widgets.markdown import MarkdownInput from core.views.widgets.select import ( diff --git a/forum/views.py b/forum/views.py index 074f496d..9501cf1b 100644 --- a/forum/views.py +++ b/forum/views.py @@ -43,7 +43,7 @@ from haystack.query import RelatedSearchQuerySet from honeypot.decorators import check_honeypot from club.widgets.select import AutoCompleteSelectClub -from core.views import ( +from core.auth.mixins import ( CanCreateMixin, CanEditMixin, CanEditPropMixin, diff --git a/galaxy/views.py b/galaxy/views.py index fe27f978..cb116d02 100644 --- a/galaxy/views.py +++ b/galaxy/views.py @@ -27,12 +27,9 @@ from django.http import Http404, JsonResponse from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, View +from core.auth.mixins import CanViewMixin, FormerSubscriberMixin from core.models import User -from core.views import ( - CanViewMixin, - FormerSubscriberMixin, - UserTabsMixin, -) +from core.views import UserTabsMixin from galaxy.models import Galaxy, GalaxyLane diff --git a/launderette/views.py b/launderette/views.py index 7886d1e7..be2bfceb 100644 --- a/launderette/views.py +++ b/launderette/views.py @@ -28,8 +28,13 @@ from django.views.generic import DetailView, ListView, TemplateView from django.views.generic.edit import BaseFormView, CreateView, DeleteView, UpdateView from club.models import Club +from core.auth.mixins import ( + CanCreateMixin, + CanEditMixin, + CanEditPropMixin, + CanViewMixin, +) from core.models import Page, User -from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from counter.forms import GetUserForm from counter.models import Counter, Customer, Selling from launderette.models import Launderette, Machine, Slot, Token diff --git a/matmat/views.py b/matmat/views.py index 47840c2d..1f037234 100644 --- a/matmat/views.py +++ b/matmat/views.py @@ -32,8 +32,9 @@ from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import FormView from phonenumber_field.widgets import RegionalPhoneNumberWidget +from core.auth.mixins import FormerSubscriberMixin from core.models import User -from core.views import FormerSubscriberMixin, search_user +from core.views import search_user from core.views.forms import SelectDate # Enum to select search type diff --git a/pedagogy/api.py b/pedagogy/api.py index d7a8d457..68e3d5e2 100644 --- a/pedagogy/api.py +++ b/pedagogy/api.py @@ -7,7 +7,7 @@ from ninja_extra import ControllerBase, api_controller, paginate, route from ninja_extra.exceptions import NotFound from ninja_extra.pagination import PageNumberPaginationExtra, PaginatedResponseSchema -from core.api_permissions import IsInGroup, IsRoot, IsSubscriber +from core.auth.api_permissions import IsInGroup, IsRoot, IsSubscriber from pedagogy.models import UV from pedagogy.schemas import SimpleUvSchema, UvFilterSchema, UvSchema from pedagogy.utbm_api import find_uv diff --git a/pedagogy/views.py b/pedagogy/views.py index c7ef0297..770dc2a4 100644 --- a/pedagogy/views.py +++ b/pedagogy/views.py @@ -35,13 +35,14 @@ from django.views.generic import ( UpdateView, ) -from core.models import Notification, User -from core.views import ( +from core.auth.mixins import ( CanCreateMixin, CanEditPropMixin, - DetailFormView, + CanViewMixin, FormerSubscriberMixin, ) +from core.models import Notification, User +from core.views import DetailFormView from pedagogy.forms import ( UVCommentForm, UVCommentModerationForm, @@ -50,8 +51,6 @@ from pedagogy.forms import ( ) from pedagogy.models import UV, UVComment, UVCommentReport -# Acutal views - class UVDetailFormView(CanViewMixin, DetailFormView): """Display every comment of an UV and detailed infos about it. diff --git a/sas/api.py b/sas/api.py index 6a25607a..96bafb87 100644 --- a/sas/api.py +++ b/sas/api.py @@ -12,7 +12,7 @@ from ninja_extra.permissions import IsAuthenticated from ninja_extra.schemas import PaginatedResponseSchema from pydantic import NonNegativeInt -from core.api_permissions import CanAccessLookup, CanView, IsInGroup, IsRoot +from core.auth.api_permissions import CanAccessLookup, CanView, IsInGroup, IsRoot from core.models import Notification, User from sas.models import Album, PeoplePictureRelation, Picture from sas.schemas import ( diff --git a/sas/views.py b/sas/views.py index 748dc718..7c8c8ea2 100644 --- a/sas/views.py +++ b/sas/views.py @@ -23,8 +23,8 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, TemplateView from django.views.generic.edit import FormMixin, FormView, UpdateView +from core.auth.mixins import CanEditMixin, CanViewMixin from core.models import SithFile, User -from core.views import CanEditMixin, CanViewMixin from core.views.files import FileView, send_file from sas.forms import ( AlbumEditForm, diff --git a/sith/settings.py b/sith/settings.py index 61079d64..9929995e 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -155,13 +155,12 @@ TEMPLATES = [ "add_attr": "core.templatetags.renderer.add_attr", }, "globals": { - "can_edit_prop": "core.views.can_edit_prop", - "can_edit": "core.views.can_edit", - "can_view": "core.views.can_view", + "can_edit_prop": "core.auth.mixins.can_edit_prop", + "can_edit": "core.auth.mixins.can_edit", + "can_view": "core.auth.mixins.can_view", "settings": "sith.settings", "Launderette": "launderette.models.Launderette", "Counter": "counter.models.Counter", - "ProductType": "counter.models.ProductType", "timezone": "django.utils.timezone", "get_sith": "com.views.sith", "get_language": "django.utils.translation.get_language", @@ -292,7 +291,7 @@ STORAGES = { # Auth configuration AUTH_USER_MODEL = "core.User" AUTH_ANONYMOUS_MODEL = "core.models.AnonymousUser" -AUTHENTICATION_BACKENDS = ["core.auth_backends.SithModelBackend"] +AUTHENTICATION_BACKENDS = ["core.auth.backends.SithModelBackend"] LOGIN_URL = "/login" LOGOUT_URL = "/logout" LOGIN_REDIRECT_URL = "/" diff --git a/trombi/views.py b/trombi/views.py index 398b4dee..7f43e199 100644 --- a/trombi/views.py +++ b/trombi/views.py @@ -38,8 +38,13 @@ from django.views.generic import DetailView, RedirectView, TemplateView, View from django.views.generic.edit import CreateView, DeleteView, UpdateView from club.models import Club +from core.auth.mixins import ( + CanCreateMixin, + CanEditMixin, + CanEditPropMixin, + CanViewMixin, +) from core.models import User -from core.views import CanCreateMixin, CanEditMixin, CanEditPropMixin, CanViewMixin from core.views.forms import SelectDate from core.views.mixins import QuickNotifMixin, TabedViewMixin from core.views.widgets.select import AutoCompleteSelectUser