Switch to HTTP Basic Auth

This commit is contained in:
Matthias Portzel 2022-01-05 16:58:50 -08:00
parent c49b7c47c4
commit e03a98cda7
5 changed files with 33 additions and 48 deletions

View File

@ -82,7 +82,7 @@ class ThoughtForm(forms.ModelForm):
widgets = {
"text": forms.Textarea(attrs={"class": "thought", "rows": 1, "placeholder": "What are you thinking?"}),
"extended_text": forms.Textarea(attrs={"class": "thought", "rows": 1, "placeholder": "Anything else?"}),
"timezone_offset": forms.HiddenInput,
"timezone_offset": forms.NumberInput,
"media_alt": forms.Textarea(attrs={"placeholder": "Media alternate text, please", "rows": 1})
}
field_classes = {

View File

@ -1,34 +0,0 @@
{% extends "whispermaphone/page.html" %}
{% load static %}
{% block title %}Post{% endblock %}
{% block head %}
<link href="{% static 'main/login.css' %}" rel="stylesheet">
{% endblock %}
{% block navigation %}
<a class="text" href="/">Thoughts</a>
<a class="text" href="/about">About</a>
<h1 class="text" aria-current="page">Login</h1>
{% endblock %}
{% block main %}
<span class="text">
Please enter the password to access this page.
</span>
<form id="password-form">
<input type="password" id="password">
<input type="submit" value="Login">
</form>
{% endblock %}
{% block scripts %}
<script>
document.getElementById("password-form").addEventListener("submit", evt => {
document.cookie = `password=${document.getElementById("password").value}; max-age=15768000; samesite=strict`;
window.location.reload();
})
</script>
{% endblock %}

View File

@ -62,7 +62,6 @@
textEl.value = value.substring(0, splitAt - 1); //Remove word and space from original
// Only move down if we're at the end of the first box
console.log(startPos, endPos);
if (startPos === 141 && endPos === 141) {
textExtEl.value = toMove + textExtEl.value;
@ -122,6 +121,9 @@
}
const timezoneOffsetEl = document.getElementById("id_timezone_offset");
timezoneOffsetEl.value = (new Date()).getTimezoneOffset();
timezoneOffsetEl.setAttribute("type", "hidden");
// The text box needs to be in hours, UTC offset (e.g. -8)
// .getTimezoneOffset() returns minutes behind UTC
timezoneOffsetEl.value = -(new Date()).getTimezoneOffset() / 60;
</script>
{% endblock %}

View File

@ -1,11 +1,13 @@
import os.path
import uuid
import subprocess
import base64
import magic
from django.shortcuts import render
from django.utils.crypto import constant_time_compare
from django.http import HttpResponse
from whispermaphone import settings
from .models import Thought, ThoughtForm, ALLOWED_MEDIA_TYPES
@ -13,13 +15,15 @@ from .models import Thought, ThoughtForm, ALLOWED_MEDIA_TYPES
from .pagination import get_all_pages, get_page_slug
def check_authenticated(request):
authenticated = False
try:
if constant_time_compare(request.COOKIES["password"], settings.PASSWORD):
authenticated = True
except KeyError:
auth = request.headers["Authorization"].split()
if auth[0].lower() == "basic":
username, password = base64.b64decode(auth[1]).split(b":")
if password == bytes(settings.PASSWORD, "utf-8"):
return True
except (KeyError, ValueError, IndexError):
pass
return authenticated
return False
def index(request):
@ -64,10 +68,23 @@ def index(request):
def post(request):
if not check_authenticated(request):
return render(request, "whispermaphone/login.html", status=401)
res = HttpResponse(status=401)
res.headers["WWW-Authenticate"] = 'Basic realm="Poster"'
return res
if request.method == "POST":
thought_form = ThoughtForm(request.POST, request.FILES, instance=Thought())
# We post in hours, so we need to convert back to minutes for saving
# We can pass errors since form.is_valid catches most of them
# We just need to convert hours to minutes first, because otherwise it errors on non-integer values
if "timezone_offset" in request.POST:
values = request.POST.copy()
try:
values["timezone_offset"] = - float(values["timezone_offset"]) * 60
except ValueError:
pass
thought_form = ThoughtForm(values, request.FILES, instance=Thought())
if not thought_form.is_valid():
errors = thought_form.errors.as_data()
# Media formatting errors
@ -116,6 +133,6 @@ def post(request):
def about(request):
authenticated = check_authenticated(request)
return render(request, "whispermaphone/about.html", {"authenticated": authenticated})
return render(request, "whispermaphone/about.html", {
"authenticated": check_authenticated(request)
})

View File

@ -65,7 +65,7 @@ MIDDLEWARE = [
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = False
ROOT_URLCONF = "whispermaphone.urls"