Search code examples
pythondjangopython-2.7django-cms

Can I change the default `login_required value for all pages in Django-CMS?


I've been tasked with creating a Django-CMS web application that should only be available to logged-in users. After some struggling I've settled to just check "Login Required" on Permissions for all pages, but it is bothersome to do this by hand (and potentially dangerous to forget to set it to true.

So I was wondering: is there a way to change the default value of the login_required BooleanField on django-cms' pagemodel.py? Or maybe I can somehow override the API's create_page method to put the default value there?

I don't know if there may be a situation in the future where we will want there to be some publicly-available pages, but if there's another way to do this rather than to set this flag to true on each Page, please let me know. I'm using Python 2.7.x, Django 1.11.x and Django-CMS 3.4.6.


Solution

  • I ended up doing it as follows:

    In the project's middleware.py I placed the following:

    from django.contrib.auth.decorators import login_required

    def login_exempt(view):
        view.login_exempt = True
        return view
    
    
    class LoginRequiredMiddleware:
        def __init__(self, get_response):
            self.get_response = get_response
    
        def __call__(self, request):
            return self.get_response(request)
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            if getattr(view_func, 'login_exempt', False):
                return
    
            if 'admin/login' in request.path:
                return
    
            if request.user.is_authenticated:
                return
    
            return login_required(view_func)(request, *view_args, **view_kwargs)
    

    Which I had to add to my settings.py's MIDDLEWARE list as 'my_project.middleware.LoginRequiredMiddleware'.

    And then in my urls.py I had to only decorate those URLs which should not require authentication:

    urlpatterns += i18n_patterns(
        url(r'^admin/', include(admin.site.urls)),
        url(r'^login/$', login_exempt(my_project_views.login_user), name='login'),
        url(r'^login$', login_exempt(my_project_views.login_user), name='login'),
        url(r'^logout$', login_exempt(my_project_views.logout_user), name='logout'),
        ...
        url(r'^', include('cms.urls')),
    )