Django-Rules работают в некоторых представлениях приложений, но не работают в других
Я интегрирую Django-Rules в свой проект для разрешений на уровне объектов. После того, как я настроил его, мне сначала удалось заставить его работать должным образом для моих приложений-моделей/ представлений Users и Profiles. Я просто не могу понять, почему она не работает для других моделей/представлений. Я написал предикаты, и когда я запускаю их независимо в оболочке, они возвращают True. Однако, когда я пытаюсь получить доступ к представлению, оно возвращает 403, а отладчик даже не показывает, что правила были проверены. Я работаю над этим уже 2 дня и буду благодарен за любую предложенную информацию.
profiles rules.py
import rules
@rules.predicate
def is_patient(user, profile):
return profile.user == user
@rules.predicate
def is_provider(user, profile):
return getattr(profile.user.patientprofile, "provider") == user
change_profile = is_patient|is_provider
view_profile = is_patient|is_provider
rules.add_rule('can_edit_profile', change_profile)
rules.add_rule('can_view_profile', view_profile)
Когда пользователь входит в представление с правильным разрешением, консоль регистрирует:
| Testing (is_patient | is_provider)
| is_patient = True
| (is_patient | is_provider) = True
Когда пользователь входит в представление с неправильным разрешением, консоль регистрирует:
| Testing (is_patient | is_provider)
| is_patient = False
| is_provider = False
| (is_patient | is_provider) = False
profiles views.py
...
from rules.contrib.views import PermissionRequiredMixin
...
class MedicalProfileUpdate(LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, UserDetailRedirectMixin, UpdateView):
model = MedicalProfile
permission_required = 'profiles.change_profile'
OtherApp rules.py
import rules
@rules.predicate
def is_patient(user, flare):
if hasattr(flare, "user"):
return flare.user == user
else:
return True
@rules.predicate
def is_provider(user, flare):
if hasattr(flare, "user"):
return getattr(flare.user.patientprofile, "provider") == user
else:
return True
change_flare = is_patient|is_provider
view_flare = is_patient|is_provider
rules.add_rule('can_edit_flare', change_flare)
rules.add_rule('can_view_flare', view_flare)
Правила здесь не проверяются.
OtherApp views.py
...
from rules.contrib.views import PermissionRequiredMixin
...
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http.response import Http404
from django.shortcuts import redirect
from django.urls import reverse
from django.views.generic import CreateView, DetailView, ListView, UpdateView
from django.views.generic.base import TemplateView
from rules.contrib.views import PermissionRequiredMixin
from ..import a bunch of project-specific stuff
User = get_user_model()
class FlareDetail(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
model = Flare
permission_required = 'flare.view_flare'
Когда пользователь пытается получить доступ к представлению, к которому он должен иметь доступ, консоль регистрирует:
gouthelper_local_django | 172.18.0.9 - - [21/Apr/2022 17:16:33] "GET /flare/4 HTTP/1.1" 301 -
gouthelper_local_django | Forbidden (Permission denied): /flare/4/
gouthelper_local_django | Traceback (most recent call last):
gouthelper_local_django | File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
gouthelper_local_django | response = get_response(request)
gouthelper_local_django | File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
gouthelper_local_django | response = wrapped_callback(request, *callback_args, **callback_kwargs)
gouthelper_local_django | File "/usr/local/lib/python3.9/contextlib.py", line 79, in inner
gouthelper_local_django | return func(*args, **kwds)
gouthelper_local_django | File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
gouthelper_local_django | return self.dispatch(request, *args, **kwargs)
gouthelper_local_django | File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/mixins.py", line 71, in dispatch
gouthelper_local_django | return super().dispatch(request, *args, **kwargs)
gouthelper_local_django | File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/mixins.py", line 103, in dispatch
gouthelper_local_django | return self.handle_no_permission()
gouthelper_local_django | File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/mixins.py", line 46, in handle_no_permission
gouthelper_local_django | raise PermissionDenied(self.get_permission_denied_message())
gouthelper_local_django | django.core.exceptions.PermissionDenied
gouthelper_local_django | 172.18.0.9 - - [21/Apr/2022 17:16:33] "GET /flare/4/ HTTP/1.1" 403 -
Не проверено ни одно правило, но в разрешении отказано.
У меня есть настройки для автообнаружения правил в каждом приложении:
'rules.apps.AutodiscoverRulesConfig',
А мои бэкенды следующие:
AUTHENTICATION_BACKENDS = [
'rules.permissions.ObjectPermissionBackend',
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
]
Опять же, любое понимание будет оценено по достоинству. Счастлив предоставить больше информации.