summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/utils.py9
-rw-r--r--core/views/user_registration.py119
2 files changed, 78 insertions, 50 deletions
diff --git a/core/utils.py b/core/utils.py
index 3db7d04..d86b901 100644
--- a/core/utils.py
+++ b/core/utils.py
@@ -277,6 +277,15 @@ def is_identified_user(user):
if user.username in ["expo", "expoadmin"]:
return False
return True
+
+def is_admin_user(user):
+ if user.is_anonymous:
+ return False
+ if user.username in ["expoadmin"]:
+ return True
+ if user.is_superuser: # set in parsers/users.py i.e. WOokey, Philip S.
+ return True
+ return False
def get_git_string(user):
if not is_identified_user(user):
diff --git a/core/views/user_registration.py b/core/views/user_registration.py
index 59990a0..6b741ab 100644
--- a/core/views/user_registration.py
+++ b/core/views/user_registration.py
@@ -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",