Add the ability to password protect pages

Useful for sharing drafts
This commit is contained in:
Jake Howard 2022-08-28 22:02:02 +01:00
parent 9ee46721c9
commit e7c4acce8b
Signed by: jake
GPG key ID: 57AFB45680EDD477
7 changed files with 99 additions and 2 deletions

View file

@ -104,3 +104,8 @@ section.hero {
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
} }
#view-restriction-banner {
text-align: center;
border-radius: 0;
}

View file

@ -0,0 +1,43 @@
body.page-password-required {
height: 100vh;
main {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-bottom: 0;
text-align: center;
}
form {
width: 80%;
max-width: 500px;
}
.input {
text-align: center;
@include dark-mode {
background-color: color.adjust($dark, $alpha: -0.2);
color: $dark-mode-text;
&::placeholder {
color: rgba(214 210 205 / 80%);
}
}
}
.errorlist {
color: $danger;
margin-bottom: 1rem;
}
h1,
p {
@include dark-mode {
color: $dark-mode-text;
}
}
}

View file

@ -19,6 +19,7 @@
@import "spotify"; @import "spotify";
@import "404"; @import "404";
@import "contact"; @import "contact";
@import "password_required";
html, html,
body { body {

View file

@ -0,0 +1,41 @@
{% extends "base.html" %}
{% load static wagtailcore_tags wagtailimages_tags %}
{% block body_class %}page-password-required{% endblock %}
{% block title %}Password required{% endblock %}
{% block extra_head %}
<meta name="robots" content="noindex" />
{% endblock %}
{% block main_content %}
<h1 class="is-size-1 has-text-primary"><i class="fa-solid fa-lock"></i></h1>
<h1 class="is-size-3 has-text-weight-bold">Password required</h1>
<p>You need a password to access this page.</p>
<form action="{{ action_url }}" method="POST" class="mt-5">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.password.errors }}
<div class="field">
<input
class="input is-medium"
type="password"
name="{{ form.password.html_name }}"
required=""
id="{{ form.password.id_for_label }}"
placeholder="Password"
>
</div>
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
<input class="button is-primary" type="submit" value="Submit" />
</form>
{% endblock %}

View file

@ -15,6 +15,12 @@
<img class="hero" src="{{ page.hero_image_url }}" decoding="async" /> <img class="hero" src="{{ page.hero_image_url }}" decoding="async" />
{% endif %} {% endif %}
{% if page.get_view_restrictions.exists %}
<section class="notification is-danger" id="view-restriction-banner">
<strong>Note</strong>: This page has a view restriction. Please do not share its content until the page is public or this message is removed.
</section>
{% endif %}
<section class="hero"> <section class="hero">
<div class="container"> <div class="container">
<div class="hero-body"> <div class="hero-body">

View file

@ -35,7 +35,7 @@ class ContentPageTestCase(TestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_queries(self) -> None: def test_queries(self) -> None:
with self.assertNumQueries(26): with self.assertNumQueries(28):
self.client.get(self.page.url) self.client.get(self.page.url)
@ -52,7 +52,7 @@ class ListingPageTestCase(TestCase):
ContentPageFactory(parent=cls.page) ContentPageFactory(parent=cls.page)
def test_accessible(self) -> None: def test_accessible(self) -> None:
with self.assertNumQueries(31): with self.assertNumQueries(33):
response = self.client.get(self.page.url) response = self.client.get(self.page.url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context["listing_pages"]), 2) self.assertEqual(len(response.context["listing_pages"]), 2)

View file

@ -187,6 +187,7 @@ BASE_HOSTNAME = env("BASE_HOSTNAME")
WAGTAILADMIN_BASE_URL = f"https://{BASE_HOSTNAME}" WAGTAILADMIN_BASE_URL = f"https://{BASE_HOSTNAME}"
WAGTAIL_FRONTEND_LOGIN_URL = "/admin/login/" WAGTAIL_FRONTEND_LOGIN_URL = "/admin/login/"
PASSWORD_REQUIRED_TEMPLATE = "password_required.html"
DEFAULT_AUTO_FIELD = "django.db.models.AutoField" DEFAULT_AUTO_FIELD = "django.db.models.AutoField"