diff options
-rw-r--r-- | core/views/user_registration.py | 53 | ||||
-rw-r--r-- | parsers/users.py | 47 | ||||
-rw-r--r-- | templates/login/register.html | 15 | ||||
-rw-r--r-- | urls.py | 1 |
4 files changed, 92 insertions, 24 deletions
diff --git a/core/views/user_registration.py b/core/views/user_registration.py index d4ce58e..72df989 100644 --- a/core/views/user_registration.py +++ b/core/views/user_registration.py @@ -2,27 +2,50 @@ from django import forms from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.core.exceptions import ValidationError
+from django.contrib.auth.models import User
+
+from troggle.core.models.troggle import DataIssue, Person
+from troggle.parsers.users import register_user
"""
This is the new individual user login registration, instead of everyone signing
in as "expo". This will be useful for the kanban expo organisation tool.
"""
-
-def register(request):
+
+def register(request, username=None):
+ """To register a new user on the troggle system, similar to the "expo" user
+ (with cavey:beery password) but specific to an individual
+ """
+ current_user = request.user
+
if request.method == "POST":
form = register_form(request.POST)
if form.is_valid():
- # <process form cleaned data>
un = form.cleaned_data["username"]
pw= form.cleaned_data["password1"]
-
+ email = form.cleaned_data["email"]
+ expoers = User.objects.filter(username=un)
+ if len(expoers) != 0:
+ # this is a password re-set, not a new registration. So we need to check it is the same person.
+ form_user = expoers[0]
+ if current_user != form_user:
+ print(f"## UNAUTHORIZED Password reset ## {current_user} {form_user}")
+ return render(request, "login/register.html", {"form": form, "unauthorized": True})
+ # create User in the system and refresh stored encrypted user list and git commit it.
+ register_user(un, email, password=pw, pwhash=None)
return HttpResponseRedirect("/accounts/login/")
else:
- form = register_form(initial={"visible": "True"})
+ if current_user:
+ form = register_form(initial={"visible": "True", "username": current_user.username})
+ elif username:
+ form = register_form(initial={"visible": "True", "username": username})
+ else:
+ form = register_form(initial={"visible": "True"})
return render(request, "login/register.html", {"form": form})
+
class register_form(forms.Form): # not a model-form, just a form-form
username = forms.CharField(strip=True, required=True,
label="Username",
@@ -33,7 +56,7 @@ class register_form(forms.Form): # not a model-form, just a form-form email = forms.CharField(strip=True, required=True,
label="email",
widget=forms.TextInput(
- attrs={"size": 35, "placeholder": "e.g. anathema@potatohut.exp",
+ attrs={"size": 35, "placeholder": "e.g. anathema@potatohut.expo",
"style": "vertical-align: text-top;"}
))
password1 = forms.CharField(strip=True, required=True,
@@ -57,4 +80,20 @@ class register_form(forms.Form): # not a model-form, just a form-form if pw1 != pw2:
raise ValidationError(
"Retyped password does not match initial password: please fix this."
- )
\ No newline at end of file + )
+ un = cleaned_data.get("username")
+ if un in ["expo", "expoadmin"]:
+ raise ValidationError(
+ "Sorry, please do not try to be clever. This username is hard-coded and you can't edit it here. We were students once, too."
+ )
+
+ expoers = Person.objects.filter(slug=un)
+ if len(expoers) == 0:
+ raise ValidationError(
+ "Sorry, we are not registering new people yet. Try again next week. We are still getting the bugs out of this.."
+ )
+ if len(expoers) != 1:
+ raise ValidationError(
+ "Sorry, that troggle identifier has duplicates. Contact a nerd on the Nerd email list, or (better) the Matrix website chat."
+ )
+
\ No newline at end of file diff --git a/parsers/users.py b/parsers/users.py index de0ce38..75145eb 100644 --- a/parsers/users.py +++ b/parsers/users.py @@ -24,6 +24,29 @@ todo = """ USERS_FILE = "users_e.json" ENCRYPTED_DIR = "encrypted" + +def register_user(u, email, password=None, pwhash=None): + try: + if existing_user := User.objects.filter(username=u): # WALRUS + print(f" - deleting existing user '{existing_user[0]}' before importing") + existing_user[0].delete() + user = User.objects.create_user(u, email) + if pwhash: + user.password = pwhash + elif password: + user.set_password(password) # function creates hash and stores hash + print(f" # hashing provided clear-text password {password} to make pwhash for user {u}") + else: + user.set_password('secret') # function creates hash and stores hash + print(f" # hashing 'secret' password to make pwhash for user {u}") + user.is_staff = False + user.is_superuser = False + user.save() + print(f" - receated and reset user '{user}'") + except Exception as e: + print(f"Exception <{e}>\n{len(User.objects.all())} users now in db:\n{User.objects.all()}") + raise + def load_users(): """These are the previously registered users of the troggle system. """ @@ -71,34 +94,30 @@ def load_users(): if userdata["encrypted"]: email = f.decrypt(email).decode() print(f" - user: '{u} <{email}>' ") - if existing_user := User.objects.filter(username=userdata["username"]): # WALRUS - # print(f" - deleting existing user '{existing_user[0]}' before importing") - existing_user[0].delete() - user = User.objects.create_user(userdata["username"], email, "secret") - user.set_password = "secret" # special attribute stores hash not password - user.is_staff = False - user.is_superuser = False - user.save() except Exception as e: - print(f"Exception <{e}>\n{len(User.objects.all())} users now in db:\n{User.objects.all()}") + print(f"Exception <{e}>\n") formatted_json = json.dumps(userdata, indent=4) print(formatted_json) raise return None + if "pwhash" in userdata: + pwhash = userdata["pwhash"] + register_user(u, email, pwhash=pwhash) + else: + register_user(u, email) else: print(f" - user: BAD username for {userdata} ") ru = [] + print(f"\n + Exporting users, encrypted emails, and password hashes") for u in User.objects.all(): - if u.username == "expo": - continue - if u.username == "expoadmin": + if u.username in ["expo", "expoadmin"]: continue e_email = f.encrypt(u.email.encode("utf8")).decode() - ru.append({"username":u.username, "email": e_email, "password": u.password, "encrypted": True}) + ru.append({"username":u.username, "email": e_email, "pwhash": u.password, "encrypted": True}) # print(u.username, e_email) original = f.decrypt(e_email).decode() - print(u.username, original) + print(f" - {u.username} - {original}") jsondict = { "registered_users": ru } encryptedfile = settings.EXPOWEB / ENCRYPTED_DIR / "encrypt.json" diff --git a/templates/login/register.html b/templates/login/register.html index 07161a0..b26b1bd 100644 --- a/templates/login/register.html +++ b/templates/login/register.html @@ -28,13 +28,21 @@ function myFunction() { </script> <div class='middle'> <h2>User registration - for a personal login to Troggle</h2> +<!--using template login/register.html --> </div> + <h3>Register a password and your email address</h3> -<!--using template login/register.html --> +{% if unauthorized %} +<span style="color:red"> +UNAUTHORIZED attempt to change password or email address. <br /> +You are not logged in as the user you are attempting to re-register. +</span>{% endif %} + <p>For previous expoers, your username must be your 'troggle id' as listed on the <a href='/people_ids'>past expoers list</a> <p>This will eventually sign you up automatically to the <a href="https://lists.wookware.org/cgi-bin/mailman/roster/expo">expo email list</a>. So type in the same email address that you use there. + <div style='width: 40%' align="right"> <form method="post" accept-charset="utf-8">{% csrf_token %} {{form.as_p}} @@ -54,8 +62,9 @@ So type in the same email address that you use there. so we can't automatically connect the troggle names and ids with the email addresses on the email list. And we don't believe in signing people up for things without their direct permission anyway. -Having said that, we <em>will</em> sign you up automatically to the expo email list as -that is how expo manages everything and it is a condition of coming on expo. +Having said that, when you register here we <em>will</em> sign you up automatically to +the expo email list as that is how expo manages everything and it is a condition of +coming on expo. <p>But the automatic sign-up to the email list is not working yet, and may not be before April 2025. So if you don't want to miss out on anything important, make sure you sign up to the @@ -168,6 +168,7 @@ trogglepatterns = [ # NB setting url pattern name to 'login' instea dof 'expologin' with override Django, see https://docs.djangoproject.com/en/dev/topics/http/urls/#naming-url-patterns path('accounts/logout/', expologout, name='expologout'), # same as in django.contrib.auth.urls path('accounts/login/', expologin, name='expologin'), # same as in django.contrib.auth.urls + path("accounts/register/<slug:username>", register, name="re_register"), path("accounts/register/", register, name="register"), path('accounts/', include('django.contrib.auth.urls')), # see site-packages\registration\auth_urls_classes.py |