implement form submission logic for the password form

This commit is contained in:
Matt Westcott 2014-06-04 15:28:03 +01:00
parent d0e93f997f
commit e4008a8148
6 changed files with 71 additions and 8 deletions

View file

@ -0,0 +1,16 @@
from django import forms
class PasswordPageViewRestrictionForm(forms.Form):
password = forms.CharField(label="Password", widget=forms.PasswordInput)
return_url = forms.CharField(widget=forms.HiddenInput)
def __init__(self, *args, **kwargs):
self.restriction = kwargs.pop('instance')
super(PasswordPageViewRestrictionForm, self).__init__(*args, **kwargs)
def clean_password(self):
data = self.cleaned_data['password']
if data != self.restriction.password:
raise forms.ValidationError("The password you have entered is not correct. Please try again.")
return data

View file

@ -812,12 +812,18 @@ class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, Indexed)):
return self.get_siblings(inclusive).filter(path__lte=self.path).order_by('-path')
password_required_template = getattr(settings, 'PASSWORD_REQUIRED_TEMPLATE', 'wagtailcore/password_required.html')
def serve_password_required_response(self, request, form):
return TemplateResponse(request, self.password_required_template, {
'self': self,
'request': request,
'form': form,
})
def serve_password_required_response(self, request, form, action_url):
"""
Serve a response indicating that the user has been denied access to view this page,
and must supply a password.
form = a Django form object containing the password input
(and zero or more hidden fields that also need to be output on the template)
action_url = URL that this form should be POSTed to
"""
context = self.get_context(request)
context['form'] = form
context['action_url'] = action_url
return TemplateResponse(request, self.password_required_template, context)
def get_navigation_menu_items():

View file

@ -5,5 +5,11 @@
</head>
<body>
<h1>Password required</h1>
<p>You need a password to access this page.</p>
<form action="{{ action_url }}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Continue" />
</form>
</body>
</html>

View file

@ -2,7 +2,10 @@ from django.conf.urls import url
from wagtail.wagtailcore import views
urlpatterns = [
# All front-end views are handled through Wagtail's core.views.serve mechanism.
url(r'^_util/authenticate_with_password/(\d+)/(\d+)/$', views.authenticate_with_password,
name='wagtailcore_authenticate_with_password'),
# Front-end page views are handled through Wagtail's core.views.serve mechanism.
# Here we match a (possibly empty) list of path segments, each followed by
# a '/'. If a trailing slash is not present, we leave CommonMiddleware to
# handle it as usual (i.e. redirect it to the trailing slash version if

View file

@ -1,8 +1,12 @@
import warnings
from django.http import HttpResponse, Http404
from django.shortcuts import get_object_or_404, redirect
from django.core.urlresolvers import reverse
from wagtail.wagtailcore import hooks
from wagtail.wagtailcore.models import Page, PageViewRestriction
from wagtail.wagtailcore.forms import PasswordPageViewRestrictionForm
def serve(request, path):
@ -26,3 +30,23 @@ def serve(request, path):
return result
return page.serve(request)
def authenticate_with_password(request, page_view_restriction_id, page_id):
"""
Handle a submission of PasswordPageViewRestrictionForm to grant view access over a
subtree that is protected by a PageViewRestriction
"""
restriction = get_object_or_404(PageViewRestriction, id=page_view_restriction_id)
page = get_object_or_404(Page, id=page_id).specific
if request.POST:
form = PasswordPageViewRestrictionForm(request.POST, instance=restriction)
if form.is_valid():
# TODO: record 'has authenticated against this page view restriction' flag in the session
return redirect(form.cleaned_data['return_url'])
else:
form = PasswordPageViewRestrictionForm(instance=restriction)
action_url = reverse('wagtailcore_authenticate_with_password', args=[restriction.id, page.id])
return page.serve_password_required_response(request, form, action_url)

View file

@ -1,8 +1,16 @@
from django.core.urlresolvers import reverse
from wagtail.wagtailcore import hooks
from wagtail.wagtailcore.models import PageViewRestriction
from wagtail.wagtailcore.forms import PasswordPageViewRestrictionForm
def check_view_restrictions(page, request):
restrictions = PageViewRestriction.objects.filter(page__in=page.get_ancestors(inclusive=True))
for restriction in restrictions:
return page.serve_password_required_response(request, None)
form = PasswordPageViewRestrictionForm(instance=restriction,
initial={'return_url': request.get_full_path()})
action_url = reverse('wagtailcore_authenticate_with_password', args=[restriction.id, page.id])
return page.serve_password_required_response(request, form, action_url)
hooks.register('before_serve_page', check_view_restrictions)