mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-16 10:47:12 +00:00
Registering existing and new users works, but is ephemeral.
This commit is contained in:
@@ -2,27 +2,50 @@ from django import forms
|
|||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.core.exceptions import ValidationError
|
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
|
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.
|
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":
|
if request.method == "POST":
|
||||||
form = register_form(request.POST)
|
form = register_form(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
# <process form cleaned data>
|
|
||||||
un = form.cleaned_data["username"]
|
un = form.cleaned_data["username"]
|
||||||
pw= form.cleaned_data["password1"]
|
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/")
|
return HttpResponseRedirect("/accounts/login/")
|
||||||
else:
|
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})
|
return render(request, "login/register.html", {"form": form})
|
||||||
|
|
||||||
|
|
||||||
class register_form(forms.Form): # not a model-form, just a form-form
|
class register_form(forms.Form): # not a model-form, just a form-form
|
||||||
username = forms.CharField(strip=True, required=True,
|
username = forms.CharField(strip=True, required=True,
|
||||||
label="Username",
|
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,
|
email = forms.CharField(strip=True, required=True,
|
||||||
label="email",
|
label="email",
|
||||||
widget=forms.TextInput(
|
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;"}
|
"style": "vertical-align: text-top;"}
|
||||||
))
|
))
|
||||||
password1 = forms.CharField(strip=True, required=True,
|
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:
|
if pw1 != pw2:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
"Retyped password does not match initial password: please fix this."
|
"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."
|
||||||
|
)
|
||||||
|
|
||||||
@@ -24,6 +24,29 @@ todo = """
|
|||||||
|
|
||||||
USERS_FILE = "users_e.json"
|
USERS_FILE = "users_e.json"
|
||||||
ENCRYPTED_DIR = "encrypted"
|
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():
|
def load_users():
|
||||||
"""These are the previously registered users of the troggle system.
|
"""These are the previously registered users of the troggle system.
|
||||||
"""
|
"""
|
||||||
@@ -71,34 +94,30 @@ def load_users():
|
|||||||
if userdata["encrypted"]:
|
if userdata["encrypted"]:
|
||||||
email = f.decrypt(email).decode()
|
email = f.decrypt(email).decode()
|
||||||
print(f" - user: '{u} <{email}>' ")
|
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:
|
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)
|
formatted_json = json.dumps(userdata, indent=4)
|
||||||
print(formatted_json)
|
print(formatted_json)
|
||||||
raise
|
raise
|
||||||
return None
|
return None
|
||||||
|
if "pwhash" in userdata:
|
||||||
|
pwhash = userdata["pwhash"]
|
||||||
|
register_user(u, email, pwhash=pwhash)
|
||||||
|
else:
|
||||||
|
register_user(u, email)
|
||||||
else:
|
else:
|
||||||
print(f" - user: BAD username for {userdata} ")
|
print(f" - user: BAD username for {userdata} ")
|
||||||
|
|
||||||
ru = []
|
ru = []
|
||||||
|
print(f"\n + Exporting users, encrypted emails, and password hashes")
|
||||||
for u in User.objects.all():
|
for u in User.objects.all():
|
||||||
if u.username == "expo":
|
if u.username in ["expo", "expoadmin"]:
|
||||||
continue
|
|
||||||
if u.username == "expoadmin":
|
|
||||||
continue
|
continue
|
||||||
e_email = f.encrypt(u.email.encode("utf8")).decode()
|
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)
|
# print(u.username, e_email)
|
||||||
original = f.decrypt(e_email).decode()
|
original = f.decrypt(e_email).decode()
|
||||||
print(u.username, original)
|
print(f" - {u.username} - {original}")
|
||||||
|
|
||||||
jsondict = { "registered_users": ru }
|
jsondict = { "registered_users": ru }
|
||||||
encryptedfile = settings.EXPOWEB / ENCRYPTED_DIR / "encrypt.json"
|
encryptedfile = settings.EXPOWEB / ENCRYPTED_DIR / "encrypt.json"
|
||||||
|
|||||||
@@ -28,13 +28,21 @@ function myFunction() {
|
|||||||
</script>
|
</script>
|
||||||
<div class='middle'>
|
<div class='middle'>
|
||||||
<h2>User registration - for a personal login to Troggle</h2>
|
<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 -->
|
<!--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>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
|
<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>.
|
<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.
|
So type in the same email address that you use there.
|
||||||
|
|
||||||
<div style='width: 40%' align="right">
|
<div style='width: 40%' align="right">
|
||||||
<form method="post" accept-charset="utf-8">{% csrf_token %}
|
<form method="post" accept-charset="utf-8">{% csrf_token %}
|
||||||
{{form.as_p}}
|
{{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
|
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
|
on the email list. And we don't believe in signing people up for things without their
|
||||||
direct permission anyway.
|
direct permission anyway.
|
||||||
Having said that, we <em>will</em> sign you up automatically to the expo email list as
|
Having said that, when you register here we <em>will</em> sign you up automatically to
|
||||||
that is how expo manages everything and it is a condition of coming on expo.
|
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.
|
<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
|
So if you don't want to miss out on anything important, make sure you sign up to the
|
||||||
|
|||||||
1
urls.py
1
urls.py
@@ -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
|
# 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/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/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/register/", register, name="register"),
|
||||||
path('accounts/', include('django.contrib.auth.urls')), # see site-packages\registration\auth_urls_classes.py
|
path('accounts/', include('django.contrib.auth.urls')), # see site-packages\registration\auth_urls_classes.py
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user