Django-Rules working in some apps views but not others
I am integrating Django-Rules into my project for object-level permissions. Once I got it configured, I was initially successful in getting it to function properly for my Users and Profiles apps-models/views. I just cannot figure out why it won't work for my others apps-models/views. I've written the predicates and when I run them independently in the shell they return True. However, when I try to access the view it returns a 403 and the debugger doesn't even indicate that the rules were checked. I have been working on this for 2 days and would appreciate any insight offered.
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)
When User enters view with correct permission, console logs:
| Testing (is_patient | is_provider)
| is_patient = True
| (is_patient | is_provider) = True
When User enters view with incorrect permission, console logs:
| 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)
Rules do not get checked here.
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'
When User tries to access a view he/she should have access to, console logs:
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 -
There aren't any rules checked, but permission is denied.
I have my settings to autodiscover rules in each app:
'rules.apps.AutodiscoverRulesConfig',
And my backends are:
AUTHENTICATION_BACKENDS = [
'rules.permissions.ObjectPermissionBackend',
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
]
Again, any insight is appreciated. Happy to provide more info.