Signup form now saving data (and encrypting it)

This commit is contained in:
2025-01-25 19:56:36 +00:00
parent c479345b6c
commit 0d105d40da
7 changed files with 190 additions and 44 deletions
+3 -12
View File
@@ -23,19 +23,10 @@ class login_required_if_public(object):
def __call__(self, *args, **kwargs):
return self.f(*args, **kwargs)
# This is copied from CUYC.cuy.website.view.auth
# If we want to do the whole online-email thing, we would also need to copy across the code in these
# imported files and delete what is superfluous.
# Or we could just load the latest version of django-registration app.
# from cuy.club.models import Member, Message
# from ..forms import WebsiteLoginForm, WebsiteRegisterForm
# from ...common import mail_site_error
# from .generic import user_is_active
"""The login and logout functions.
This is also where we would manage registration: for people wanting to create and validate their individual
logon accounts/forgottenpassword"""
TO DO : check that we don't have another set of these active somewhere
"""
############################
# Authentication Functions #
+137 -25
View File
@@ -1,8 +1,8 @@
import os
import re
import json
from pathlib import Path
import django.forms as forms
from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect, render
from django.urls import reverse
@@ -16,62 +16,174 @@ from troggle.core.utils import (
git_string,
write_and_commit,
)
from troggle.core.models.troggle import DataIssue, Person
from troggle.core.views.editor_helpers import HTMLarea
from troggle.core.utils import (
add_commit,
)
from troggle.parsers.users import get_encryptor, ENCRYPTED_DIR
"""The new user signup form and expo user management system in 2025.
"""
SIGNUPS_FILE = "signups.json"
SIGNEDUP = "SIGNEDUP"
SIGNUP_YEAR = "2025"
SIGNUP_DATES = "30th June - 3rd August"
def signupok(request):
signup_user = request.user
return render(
request, "login/signupok.html",
{"year": SIGNUP_YEAR, "dates": SIGNUP_DATES, "signup_user": signup_user },
)
def signup(request):
current_user = request.user
"""Display and processes the applicant signup form for the forthcoming expo
The user must be logged-on as a personal login and that is
who is being sighned up. You can't signup someone else.
"""
signup_user = request.user
personal_login = True
if current_user.is_anonymous:
if signup_user.is_anonymous:
personal_login = False
elif current_user.username in ["expo", "expoadmin"]:
elif signup_user.username in ["expo", "expoadmin"]:
personal_login = False
else:
personal_login = True
if personal_login:
people = Person.objects.filter(user=signup_user)
if len(people) != 1:
# someone like "fluffy-bunny" not associated with a Person
return HttpResponseRedirect("/accounts/login/?next=/signup")
signup_person = people[0]
editor = f"{signup_person.fullname} <{signup_user.email}>"
if request.method == "POST": # If the form has been submitted...
pageform = ExpoSignupForm(request.POST) # A form bound to the POST data
if pageform.is_valid():
print(f"form OK")
who = pageform.cleaned_data["name"]
who = git_string(name)
print(f"{who=}")
clean = pageform.cleaned_data
print(f" # Signup form OK {clean['name']}")
save_signups(editor, signup_person.slug, clean)
return HttpResponseRedirect("/signupok")
else:
print(f" # Signup form INVALID\n{pageform.errors} ")
return render(
request,
"login/signup.html",
request, "login/signup.html",
{"form": pageform, "personal_login": personal_login,
"year": "2025", "dates": "30th June - 3rd August",
"year": SIGNUP_YEAR, "dates": SIGNUP_DATES,
}
)
else:
pageform = ExpoSignupForm(initial={"allergies":"None",
initial_context = {"allergies":"None",
"medication":"None",
"medic_info":"None",
"veggie": "mostly",
"student": "no",
"top_tent_cap": 2,
"base_tent_cap": 3,
})
}
if personal_login:
initial_context["name"] = signup_person.fullname
initial_context["email"] = signup_user.email
pageform = ExpoSignupForm(initial=initial_context)
return render(
request,
"login/signup.html",
{"form": pageform,
"year": "2025", "dates": "30th June - 3rd August",
request, "login/signup.html",
{"form": pageform, "personal_login": personal_login,
"year": SIGNUP_YEAR, "dates": SIGNUP_DATES,
},
)
def read_signups():
print(f" + READ signups")
f = get_encryptor()
signups_dir = settings.EXPOWEB / ENCRYPTED_DIR / current_expo()
if not signups_dir.is_dir():
signups_dir.mkdir(parents=True, exist_ok=True)
signupsfile = signups_dir / SIGNUPS_FILE
if not signupsfile.is_file():
return { SIGNEDUP: {} } # dict where e.g. {"philip-sargent": encrypted_form_data, more users etc.}
with open(signupsfile, 'r', encoding='utf-8') as json_f:
message = ""
try:
signups_single_dict = json.load(json_f)
except FileNotFoundError:
message = f"File {signupsfile} not found!"
except json.JSONDecodeError:
message = f"Invalid JSON format! - JSONDecodeError for {signupsfile}"
except Exception as e:
message = f"! Troggle USERs. Failed to load {signupsfile} JSON file. Exception <{e}>"
if message:
print(message)
DataIssue.objects.update_or_create(parser="_signups", message=message, url="") ###########################
return { SIGNEDUP: {} }
signups_dict = signups_single_dict[SIGNEDUP]
# print("ALL:",signups_dict)
signups_clear ={}
for su, content in signups_dict.items():
clear_text = f.decrypt(content).decode()
print(f"\n - C signups_dict {su} - {clear_text}")
signups_clear[su] = clear_text
return signups_clear
def save_signups(editor, person_slug, clean):
# print(f" + SAVE: Saving all signups")
f = get_encryptor()
signups_clear = read_signups()
# print(f" SAVE: {len(signups_clear)} signups read")
signups_clear[person_slug] = clean
signups_crypt = {}
for su in signups_clear:
# re-encrypt everything
signups_crypt[su] = f.encrypt(json.dumps(signups_clear[su]).encode("utf8")).decode()
print(f" SAVE after adding: {len(signups_crypt)} signups")
encryptedfile = settings.EXPOWEB / ENCRYPTED_DIR / current_expo() / SIGNUPS_FILE
try:
print(f"- Rewriting the entire encrypted set of signups to disc ")
write_signups(signups_crypt, encryptedfile, editor)
except:
message = f'! - Users encrypted data saving failed - \n!! Permissions failure ?! on attempting to save file "{encryptedfile}"'
print(message)
raise
return render(request, "errors/generic.html", {"message": message})
def write_signups(signups, encryptedfile, editor):
jsondict = { SIGNEDUP: signups }
try:
with open(encryptedfile, 'w', encoding='utf-8') as json_f:
json.dump(jsondict, json_f, indent=1)
except Exception as e:
print(f" ! Exception dumping json <{e}>")
raise
commit_msg = f"Online signup to next expo"
try:
add_commit(encryptedfile, commit_msg, editor)
except Exception as e:
print(f" ! Exception doing git add/commit <{e}>")
raise
return True
class ExpoSignupForm(forms.Form):
name = forms.CharField(label='Full name', max_length=100, widget=forms.TextInput(attrs={'tabindex': 1, 'placeholder': 'Anathema Device'}))
address = forms.CharField(widget=forms.Textarea(attrs={'rows': 7, 'cols': 20, 'tabindex': 2, 'placeholder': 'The Airfield,\nTadfield'}))
phone = forms.CharField(max_length=15, widget=forms.TextInput(attrs={'tabindex': 3, 'placeholder': '+44.1234567890'}))
email = forms.EmailField(widget=forms.TextInput(attrs={'tabindex': 4, 'placeholder': 'a.device@potatohut.expo'}))
kinname = forms.CharField(label='Next of Kin name', max_length=100, widget=forms.TextInput(attrs={'tabindex': 5, 'placeholder': 'Newton Pulsifer'}))
kinaddress = forms.CharField(widget=forms.Textarea(attrs={'rows': 7, 'cols': 20, 'tabindex': 6, 'placeholder': 'c/o The Old Ship Inn,\nLower Tadfield'}))
kinphone = forms.CharField(max_length=15, widget=forms.TextInput(attrs={'tabindex': 7, 'placeholder': '+44.0987654321'}))
kinemail = forms.EmailField(widget=forms.TextInput(attrs={'tabindex': 8, 'placeholder': 'n.pulsifer@basecamp.expo'}))
kin_name = forms.CharField(label='Next of Kin name', max_length=100, widget=forms.TextInput(attrs={'tabindex': 5, 'placeholder': 'Newton Pulsifer'}))
kin_address = forms.CharField(widget=forms.Textarea(attrs={'rows': 7, 'cols': 20, 'tabindex': 6, 'placeholder': 'c/o The Old Ship Inn,\nLower Tadfield'}))
kin_phone = forms.CharField(max_length=15, widget=forms.TextInput(attrs={'tabindex': 7, 'placeholder': '+44.0987654321'}))
kin_email = forms.EmailField(widget=forms.TextInput(attrs={'tabindex': 8, 'placeholder': 'n.pulsifer@basecamp.expo'}))
relation = forms.CharField(label='Relation to you', max_length=100, widget=forms.TextInput(attrs={'tabindex': 9, 'placeholder': 'Beau'}))
VEGGIE_CHOICES = [