2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2025-12-15 07:27:09 +00:00

Registering existing and new users works, but is ephemeral.

This commit is contained in:
2025-01-21 01:15:13 +00:00
parent b34ad3a82b
commit 01afb09a6e
4 changed files with 93 additions and 25 deletions

View File

@@ -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."
)
)
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."
)

View File

@@ -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"

View File

@@ -28,13 +28,21 @@ function myFunction() {
</script>
<div class='middle'>
<h2>User registration - for a personal login to Troggle</h2>
</div>
<h3>Register a password and your email address</h3>
<!--using template login/register.html -->
</div>
<h3>Register a password and your email address</h3>
{% 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

View File

@@ -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