diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/utils.py | 1 | ||||
-rw-r--r-- | core/views/auth.py | 15 | ||||
-rw-r--r-- | core/views/signup.py | 162 |
3 files changed, 140 insertions, 38 deletions
diff --git a/core/utils.py b/core/utils.py index b6ec7af..33872b3 100644 --- a/core/utils.py +++ b/core/utils.py @@ -135,7 +135,6 @@ def make_new_expo_dir(year): if not p.is_file(): write_and_commit( [(p, content, "utf8")], f"Auto new year {ff} file creation", "Auto New Year <make_new_expo_dir@troggle.expo>") - def current_expo(): """Returns the current expo year, but also checks if the most recent expo year is the same as this year. If it is not, then it creates an empty Expedition and fixes some files and diff --git a/core/views/auth.py b/core/views/auth.py index db17ae3..689e645 100644 --- a/core/views/auth.py +++ b/core/views/auth.py @@ -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 # diff --git a/core/views/signup.py b/core/views/signup.py index 686c92d..bc10b7a 100644 --- a/core/views/signup.py +++ b/core/views/signup.py @@ -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 = [ |