mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-18 10:57:11 +00:00
only allows registration once, except for admins
This commit is contained in:
@@ -13,19 +13,24 @@ 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
|
||||
is_identified_user,
|
||||
is_admin_user,
|
||||
)
|
||||
from troggle.core.views.auth import expologout
|
||||
|
||||
"""
|
||||
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.. maybe?
|
||||
This is the new 2025 individual user login registration, instead of everyone signing
|
||||
in as "expo". This may be useful for the kanban expo organisation tool. It also will
|
||||
eventually (?) replace the cookie system for assigning responsibility to git commits.
|
||||
|
||||
This registration system has logic spread between these functions and the Django templates.
|
||||
It seriously needs refactoring as the logic is opaque. Before that, it needs a full set of
|
||||
tests to check all the combinations of users/logged-on/pre-registered/admin etc. etc.
|
||||
"""
|
||||
|
||||
todo = """
|
||||
- Make all this work with New people who have never been on expo before
|
||||
- Stop anyone re-registering an email for an id which already has an email
|
||||
|
||||
- Make all this work with New people who have never been on expo before - add a queue/email to be approved by an admin
|
||||
- Stop anyone re-registering an email for an id which already has an email (unless by an admin)
|
||||
- login automatically, and redirect to control panel ?
|
||||
"""
|
||||
|
||||
@@ -47,7 +52,7 @@ class ExpoPasswordResetForm(PasswordResetForm):
|
||||
return email
|
||||
|
||||
def reset_done(request):
|
||||
"""This page is called when a password reset has successively occured
|
||||
"""This page is called when a password reset has successively occurred.
|
||||
Unfortunately by this point, we do not know the name of the user who initiated the
|
||||
password reset, so when we do the git commit of the encrypted users file
|
||||
we do not have a name to put to the responsible person. To do that,
|
||||
@@ -70,11 +75,13 @@ def reset_done(request):
|
||||
|
||||
def newregister(request, username=None):
|
||||
"""To register a COMPLETELY new user on the troggle system,
|
||||
WITHOUT any previous expo attendance.
|
||||
WITHOUT any previous expo attendance. Currently allows random anyone to add suff to our system. Yuk.
|
||||
This is DISABLED pending implementing a queue/confirm mechanism
|
||||
except for admin users.
|
||||
"""
|
||||
current_user = request.user # if not logged in, this is 'AnonymousUser'
|
||||
warning = ""
|
||||
|
||||
|
||||
if request.method == "POST":
|
||||
form = newregister_form(request.POST)
|
||||
if form.is_valid():
|
||||
@@ -84,14 +91,16 @@ def newregister(request, username=None):
|
||||
nameslug = troggle_slugify(fullname)
|
||||
print(f"NEW user slug {nameslug}")
|
||||
|
||||
expoers = User.objects.filter(username=nameslug)
|
||||
if len(expoers) != 0:
|
||||
if User.objects.filter(username=nameslug).count() != 0:
|
||||
# Disallow a name which already exists, use the other form.
|
||||
return HttpResponseRedirect(f"/accounts/register/{nameslug}")
|
||||
# create User in the system and refresh stored encrypted user list and git commit it:
|
||||
updated_user = register_user(nameslug, email, password=None, pwhash=None, fullname=fullname)
|
||||
save_users(request, updated_user, email)
|
||||
return HttpResponseRedirect("/accounts/password_reset/")
|
||||
if is_admin_user(request.user):
|
||||
updated_user = register_user(nameslug, email, password=None, pwhash=None, fullname=fullname)
|
||||
save_users(request, updated_user, email)
|
||||
return HttpResponseRedirect("/accounts/password_reset/")
|
||||
else:
|
||||
return render(request, "login/register.html", {"form": form, "warning": "Only ADMINs can do this", "newuser": True})
|
||||
else: # GET
|
||||
form = newregister_form(initial={"visible-passwords": "True"})
|
||||
|
||||
@@ -105,7 +114,7 @@ def re_register_email(request):
|
||||
|
||||
and we ignore any username specified in the URL of the request.
|
||||
"""
|
||||
logged_in = (identified_login := is_identified_user(request.user))
|
||||
logged_in = (identified_login := is_identified_user(request.user)) # logged_in used on form
|
||||
if not logged_in:
|
||||
return HttpResponseRedirect("/accounts/login/")
|
||||
|
||||
@@ -130,50 +139,60 @@ def re_register_email(request):
|
||||
form = register_email_form(initial=initial_values)
|
||||
return render(request, "login/register_email.html", {"form": form})
|
||||
|
||||
def reshow_disabled(request, url_username, initial_values, warning, admin_notice):
|
||||
"""Shows the form, but completely disabled, with messages showing what the user did
|
||||
wrong or inappropriately. Could all be replaced by form validation methods ?
|
||||
"""
|
||||
print(warning)
|
||||
print(admin_notice)
|
||||
form = register_form(initial=initial_values)
|
||||
form.fields["username"].widget.attrs["readonly"]="readonly"
|
||||
form.fields["email"].widget.attrs["readonly"]="readonly"
|
||||
form.fields["password1"].widget.attrs["readonly"]="readonly"
|
||||
form.fields["password2"].widget.attrs["readonly"]="readonly"
|
||||
|
||||
return render(request, "login/register.html", {"form": form, "admin_notice": admin_notice, "warning": warning})
|
||||
# not used, loops: return HttpResponse warning, admin_notice): Redirect(f"/accounts/login/?next=/accounts/register/{url_username}")
|
||||
|
||||
|
||||
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
|
||||
for someone who has previously attended expo.
|
||||
Authority this gives is the same as the "expo" user
|
||||
(with cavey:beery password) but specific to an individual.
|
||||
|
||||
We should only allow this to be done ONCE for each user-id.
|
||||
|
||||
|
||||
"""
|
||||
warning = ""
|
||||
admin_notice = ""
|
||||
initial_values={"visible-passwords": "True"}
|
||||
print(f"{url_username=}")
|
||||
print(f"{url_username=} {request.user.username=}")
|
||||
|
||||
if request.user.is_anonymous:
|
||||
# Anonymous users are not logged in as anybody. Which is what we expect
|
||||
pass
|
||||
else:
|
||||
logged_in = (identified_login := is_identified_user(request.user))
|
||||
if logged_in:
|
||||
# logged in as a known real person with a User logon
|
||||
print(f"Already logged in as {identified_login=}, redirecting to re_register_email()")
|
||||
return re_register_email(request) # discarding url_username
|
||||
else:
|
||||
print(f"user is logged in as somebody (but not an identified person, so must be 'expo')")
|
||||
# logout invisibly before we do anything, 'expo' is irrelevant; but 'expoadmin' is significant!
|
||||
# , redirecting to expologout()
|
||||
pass
|
||||
# expologout(request) # returns a response, which we discard
|
||||
|
||||
# At this point we know the request user is not logged in at all.
|
||||
if url_username: # if provided in URL
|
||||
print(url_username, "Person count",Person.objects.filter(slug=url_username).count())
|
||||
if Person.objects.filter(slug=url_username).count() != 1:
|
||||
# not an old expoer, so redirect to the other form
|
||||
# Since this form is for old expoers, we can expect that they know how to login as 'expo'. So require this at least.
|
||||
if request.user.is_anonymous:
|
||||
warning = "ANONYMOUS users not allowed to Register old expoers. Login, e.g. as 'expo', and try again."
|
||||
return reshow_disabled(request, url_username, initial_values, warning, admin_notice)
|
||||
|
||||
if url_username: # if provided in URL, but if POST then this could alternatively be in the POST data field ["username"]
|
||||
# print(url_username, "Person count",Person.objects.filter(slug=url_username).count())
|
||||
# print(url_username, "User count",User.objects.filter(username=url_username).count())
|
||||
|
||||
if (Person.objects.filter(slug=url_username).count() != 1):
|
||||
# not an old expoer, so redirect to the other form for completely new cavers,
|
||||
# but suppose it was a typo? Better to check this in response to a POST surely?
|
||||
# To do: do this as a form-valiation action.
|
||||
return HttpResponseRedirect("/accounts/newregister/")
|
||||
# This is where we need to check that this url_username has or has not already been registered.
|
||||
print(url_username, "User count",User.objects.filter(username=url_username).count())
|
||||
if User.objects.filter(username=url_username).count() == 1:
|
||||
# Do not allow registration unless superuser is logged in, oops, need to refactor/reorder
|
||||
pass
|
||||
admin_notice = "ADMIN PRIViedge ?!"
|
||||
|
||||
|
||||
already_registered = (User.objects.filter(username=url_username).count() == 1)
|
||||
if already_registered:
|
||||
if is_admin_user(request.user):
|
||||
admin_notice = "ADMIN OVERRIDE ! Can re-set everything." # can proceed to reset everything
|
||||
else:
|
||||
admin_notice = f"This former expoer '{url_username}' already has a registered email address and individual troggle access password."
|
||||
return reshow_disabled(request, url_username, initial_values, warning, admin_notice)
|
||||
|
||||
logged_in = (identified_login := is_identified_user(request.user)) # used on the form
|
||||
|
||||
if url_username:
|
||||
initial_values.update({"username": url_username})
|
||||
form = register_form(initial=initial_values)
|
||||
form.fields["username"].widget.attrs["readonly"]="readonly"
|
||||
@@ -256,7 +275,7 @@ def write_users(registered_users, encryptedfile, git_string):
|
||||
|
||||
class newregister_form(forms.Form): # not a model-form, just a form-form
|
||||
"""This is the form for a new user who has not been on expo before and
|
||||
does notalready have a username
|
||||
does notalready have a username.
|
||||
"""
|
||||
fullname = forms.CharField(strip=True, required=True,
|
||||
label="Forename Surname",
|
||||
|
||||
Reference in New Issue
Block a user