manage: force user to be logged in as staff to access management pages (#6278)

This commit is contained in:
Frédéric Péters 2015-01-12 09:19:48 +01:00
parent 85d26f199e
commit 3ed5b2c4eb
5 changed files with 98 additions and 3 deletions

View File

@ -6,6 +6,7 @@
{% block footer %}Combo — Copyright © Entr'ouvert{% endblock %}
{% block homepage-url %}{% url 'combo-manager-homepage' %}{% endblock %}
{% block logout-url %}{% url 'auth_logout' %}{% endblock %}
{% block extrascripts %}
<script src="{% static "ckeditor/ckeditor/ckeditor.js" %}"></script>

View File

@ -0,0 +1,10 @@
{% extends "combo/manager_base.html" %}
{% load i18n %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="{% trans 'Log in' %}" />
</form>
{% endblock %}

View File

@ -15,12 +15,21 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.conf import settings
from django.contrib.auth import logout as auth_logout
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.shortcuts import get_object_or_404, render
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render, resolve_url
from combo.data.models import CellBase, Page
def logout(request, next_page=None):
auth_logout(request)
if next_page is not None:
next_page = resolve_url(next_page)
else:
next_page = '/'
return HttpResponseRedirect(next_page)
def page(request):
parts = [x for x in request.path_info.strip('/').split('/') if x]
if not parts:

View File

@ -17,9 +17,17 @@
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.contrib.auth.decorators import login_required
from django.contrib.auth import views as auth_views
from .urls_utils import decorated_includes, manager_required
from .public.views import logout
from .manager.urls import urlpatterns as combo_manager_urls
urlpatterns = patterns('',
url(r'^manage/', include('combo.manager.urls')),
url(r'^manage/', decorated_includes(manager_required,
include(combo_manager_urls))),
url(r'^admin/', include(admin.site.urls)),
)
@ -30,5 +38,10 @@ urlpatterns += staticfiles_urlpatterns()
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += patterns('',
url(r'^accounts/login/$', auth_views.login),
url(r'^accounts/logout/$', logout, name='auth_logout'),
)
# other URLs are handled as public URLs
urlpatterns += patterns('', url(r'', include('combo.public.urls')))

62
combo/urls_utils.py Normal file
View File

@ -0,0 +1,62 @@
# combo - content management system
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Decorating URL includes, <https://djangosnippets.org/snippets/2532/>
from django.contrib.auth.decorators import user_passes_test
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import RegexURLPattern, RegexURLResolver
class DecoratedURLPattern(RegexURLPattern):
def resolve(self, *args, **kwargs):
result = super(DecoratedURLPattern, self).resolve(*args, **kwargs)
if result:
result.func = self._decorate_with(result.func)
return result
class DecoratedRegexURLResolver(RegexURLResolver):
def resolve(self, *args, **kwargs):
result = super(DecoratedRegexURLResolver, self).resolve(*args, **kwargs)
if result:
result.func = self._decorate_with(result.func)
return result
def decorated_includes(func, includes, *args, **kwargs):
urlconf_module, app_name, namespace = includes
for item in urlconf_module:
if isinstance(item, RegexURLPattern):
item.__class__ = DecoratedURLPattern
item._decorate_with = func
elif isinstance(item, RegexURLResolver):
item.__class__ = DecoratedRegexURLResolver
item._decorate_with = func
return urlconf_module, app_name, namespace
def manager_required(function=None, login_url=None):
def check_manager(user):
if user and user.is_staff:
return True
if user and not user.is_anonymous():
raise PermissionDenied()
# As the last resort, show the login form
return False
actual_decorator = user_passes_test(check_manager, login_url=login_url)
if function:
return actual_decorator(function)
return actual_decorator