2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2026-02-08 11:49:50 +00:00

password reset for logged-on users now working

This commit is contained in:
2025-01-27 15:15:54 +00:00
parent 6d25f70491
commit 1825ed55fc
5 changed files with 264 additions and 75 deletions

View File

@@ -13,7 +13,8 @@ from troggle.parsers.users import register_user, get_encryptor, ENCRYPTED_DIR, U
from troggle.parsers.people import troggle_slugify
from troggle.core.utils import (
add_commit,
)
is_identified_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.
@@ -27,7 +28,7 @@ todo = """
class ExpoPasswordResetForm(PasswordResetForm):
"""Because we are using the Django-standard django.contrib.auth mechanisms, the way Django wants us to
modify them is to subclass their stuff and insert our extras in teh subclasses. This is completely
modify them is to subclass their stuff and insert our extras in the subclasses. This is completely
unlike how the rest of troggle works because we avoid Class-based views.
We avoid them because they are very hard to debug for newcomer programmers who don't know Django:
the logic is spread out up a tree of preceding ancestor classes.
@@ -89,21 +90,61 @@ def newregister(request, username=None):
save_users(request, updated_user, email)
return HttpResponseRedirect("/accounts/password_reset/")
else: # GET
form = newregister_form(initial={"visible": "True"})
form = newregister_form(initial={"visible-passwords": "True"})
return render(request, "login/register.html", {"form": form, "warning": warning, "newuser": True})
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 not logged in, this is 'AnonymousUser'
warning = ""
def re_register_email(request):
"""For a logged-on user:
- change the email address
- trigger reset password ( by email token)
and we ignore any username specified in the URL of the request.
"""
logged_in = (identified_login := is_identified_user(request.user))
if not logged_in:
return HttpResponseRedirect("/accounts/login/")
u = request.user
initial_values = {}
initial_values.update({"username": u.username})
initial_values.update({"email": u.email})
if request.method == "POST":
form = register_email_form(request.POST) # only username and password
if form.is_valid():
print("POST VALID")
email = form.cleaned_data["email"]
u.email = email
u.save()
save_users(request, u, email)
return render(request, "login/register_email.html", {"form": form, "confirmed": True})
else:
print("POST INVALID")
return render(request, "login/register_email.html", {"form": form})
else: # GET
form = register_email_form(initial=initial_values)
return render(request, "login/register_email.html", {"form": form})
def register(request, url_username=None):
"""To register an old expoer as a new user on the troggle system,
for someone who has previously attended expo,
similar to the "expo" user
(with cavey:beery password) but specific to an individual.
"""
warning = ""
initial_values={"visible-passwords": "True"}
logged_in = (identified_login := is_identified_user(request.user))
if logged_in:
return re_register_email(request)
if request.method == "POST":
form = register_form(request.POST)
if form.is_valid():
print("POST VALID")
un = form.cleaned_data["username"]
pw= form.cleaned_data["password1"]
email = form.cleaned_data["email"]
@@ -112,7 +153,7 @@ def register(request, username=None):
# 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}")
print(f"## UNAUTHORIZED Password reset ## {request.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:
updated_user = register_user(un, email, password=pw, pwhash=None)
@@ -120,19 +161,16 @@ def register(request, username=None):
# to do, login automatically, and redirect to control panel ?
return HttpResponseRedirect("/accounts/login/")
else: # GET
if username: # if provided in URL
if not current_user.is_anonymous:
warning = f"WARNING - you are logged-in as someone else '{current_user}'. You must logout and login again as '{username}' "
if url_username: # if provided in URL
if not request.user.is_anonymous:
warning = f"WARNING - you are logged-in as someone else '{request.user}'. You must logout and login again as '{url_username}' "
print(f"REGISTER: {warning}")
form = register_form(initial={"visible": "True", "username": username} )
elif current_user:
form = register_form(initial={"visible": "True", "username": current_user.username})
else:
form = register_form(initial={"visible": "True"})
return render(request, "login/register.html", {"form": form, "warning": warning})
initial_values.update({"username": url_username})
elif request.user:
initial_values.update({"username": request.user.username})
form = register_form(initial=initial_values)
return render(request, "login/register.html", {"form": form, "warning": warning, "logged_in": logged_in})
def save_users(request, updated_user, email="troggle@exposerver.expo"):
@@ -215,8 +253,37 @@ class newregister_form(forms.Form): # not a model-form, just a form-form
"If you have been on expo before, you need to use the other form at expo.survex.com/accounts/register/ ."
)
class register_email_form(forms.Form): # not a model-form, just a form-form
"""The widgets are being used EVEN THOUGH we are not using form.as_p() to create the
HTML form"""
username = forms.CharField(strip=True, required=True,
label="Username",
widget=forms.TextInput(
attrs={"size": 35, "placeholder": "e.g. anathema-device",
"style": "vertical-align: text-top;", "readonly": "readonly"} # READONLY for when changing email
))
email = forms.CharField(strip=True, required=True,
label="email",
widget=forms.TextInput(
attrs={"size": 35, "placeholder": "e.g. anathema@potatohut.expo",
"style": "vertical-align: text-top;"}
))
def clean(self):
cleaned_data = super().clean()
email = cleaned_data.get("email")
users = User.objects.filter(email=email)
print(f"{len(users)=}")
if len(users) > 1: # allow 0 (change) or 1 (confirm)
print("ValidationError")
raise ValidationError(
"Duplicate email address. Another registered user is already using this email address. Email addresses must be unique as that is how we reset forgotten passwords."
)
class register_form(forms.Form): # not a model-form, just a form-form
"""The widgets are being used EVEN THOUGH we are not using form.as_p() to create the
HTML form"""
username = forms.CharField(strip=True, required=True,
label="Username",
widget=forms.TextInput(