diff options
author | Philip Sargent <philip.sargent@gmail.com> | 2025-01-22 23:03:01 +0000 |
---|---|---|
committer | Philip Sargent <philip.sargent@gmail.com> | 2025-01-22 23:03:01 +0000 |
commit | 173ee2348fd8d6b4f799ac606b98f6d0da8f6935 (patch) | |
tree | 6a4cff0333221d7a7b1dcf604212aef030501e44 | |
parent | a5341c4eb256d7d18bddca597c97a9fb91794ea6 (diff) | |
download | troggle-173ee2348fd8d6b4f799ac606b98f6d0da8f6935.tar.gz troggle-173ee2348fd8d6b4f799ac606b98f6d0da8f6935.tar.bz2 troggle-173ee2348fd8d6b4f799ac606b98f6d0da8f6935.zip |
password reset via encrypted token by email
-rw-r--r-- | core/views/other.py | 6 | ||||
-rw-r--r-- | core/views/user_registration.py | 42 | ||||
-rw-r--r-- | settings.py | 3 | ||||
-rw-r--r-- | templates/login/register.html | 13 | ||||
-rw-r--r-- | urls.py | 11 |
5 files changed, 53 insertions, 22 deletions
diff --git a/core/views/other.py b/core/views/other.py index f1cd6ac..f1a7bdf 100644 --- a/core/views/other.py +++ b/core/views/other.py @@ -121,9 +121,10 @@ def controlpanel(request): jobs_completed = [] def process_imports(): - """databaseReset.py + """databaseReset.py - CHECK THIS IS ALL CORRECT& CURRENT IF YOU RE-ENABLE IT jq.enq("reinit",reinit_db) jq.enq("caves",import_caves) + jq.enq("users",import_users) jq.enq("people",import_people) jq.enq("scans",import_surveyscans) jq.enq("logbooks",import_logbooks) @@ -136,6 +137,7 @@ def controlpanel(request): jobs_completed.append("Caves") if request.POST.get("import_people", False): import_people() + jobs_completed.append("People") if request.POST.get("import_surveyscans", False): import_surveyscans() @@ -187,7 +189,7 @@ def exportlogbook(request, year=None): There are no images stored in the database. However links to images work in the HTML text of a logbook entry. - This function is the recipient of the POST action as the export form in the control panel + This function is the recipient of the POST action as the export form in the control panel (now disabled). """ def lbeKey(lbe): diff --git a/core/views/user_registration.py b/core/views/user_registration.py index fe9f126..1f8e47f 100644 --- a/core/views/user_registration.py +++ b/core/views/user_registration.py @@ -23,7 +23,23 @@ todo = """ - login automatically, and redirect to control panel ?
"""
-
+def reset_done(request):
+ """This page is called when a password reset has successively occured
+ 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,
+ we would have to intercept at the previous step, the url:
+ "reset/<uidb64>/<token>/",
+ views.PasswordResetConfirmView.as_view(),
+ and this class-based view is a lot more complicated to replace or sub-class.
+
+ Currently we are doing the git commit anonymously.. though I guess we could attempt to
+ read the cookie... if it is set.
+ """
+ current_user = request.user
+ save_users(request, current_user)
+ return HttpResponseRedirect("/accounts/login/")
+
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
@@ -46,7 +62,7 @@ def register(request, username=None): # 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)
- save_users(request, updated_user, email)
+ save_users(request, updated_user)
# to do, login automatically, and redirect to control panel ?
return HttpResponseRedirect("/accounts/login/")
else:
@@ -63,9 +79,12 @@ def register(request, username=None): return render(request, "login/register.html", {"form": form, "warning": warning})
-def save_users(request, updated_user, email):
+
+
+def save_users(request, updated_user):
f = get_encryptor()
ru = []
+
print(f"\n + Saving users, encrypted emails, and password hashes")
for u in User.objects.all():
if u.username in ["expo", "expoadmin"]:
@@ -76,29 +95,32 @@ def save_users(request, updated_user, email): original = f.decrypt(e_email).decode()
print(f" - {u.username} - {original}")
+ if updated_user.is_anonymous:
+ git_string = f"troggle <troggle@exposerver.expo>"
+ else:
+ git_string = f"{updated_user.username} <{email}>"
encryptedfile = settings.EXPOWEB / ENCRYPTED_DIR / USERS_FILE
try:
print(f"- Rewriting the entire encrypted set of registered users to disc ")
- write_users(ru, encryptedfile, updated_user, email)
+ write_users(ru, encryptedfile, git_string)
except:
message = f'! - Users encrypted data saving failed - \n!! Permissions failure ?! on attempting to save file "{encryptedfile}"'
print(message)
+ raise
return render(request, "errors/generic.html", {"message": message})
-def write_users(registered_users, encryptedfile, updated_user, email):
+def write_users(registered_users, encryptedfile, git_string):
jsondict = { "registered_users": registered_users }
try:
- if settings.DEVSERVER:
- with open(encryptedfile, 'w', encoding='utf-8') as json_f:
- json.dump(jsondict, json_f, indent=1)
+ with open(encryptedfile, 'w', encoding='utf-8') as json_f:
+ json.dump(jsondict, json_f, indent=1)
except Exception as e:
print(f" ! Exception dumping json <{e}>")
raise
commit_msg = f"Online (re-)registration of a troggle User"
- editor = f"{updated_user.username} <{email}>"
try:
- add_commit(encryptedfile, commit_msg, editor)
+ add_commit(encryptedfile, commit_msg, git_string)
except Exception as e:
print(f" ! Exception doing git add/commit <{e}>")
raise
diff --git a/settings.py b/settings.py index d201b4c..22dd31e 100644 --- a/settings.py +++ b/settings.py @@ -86,6 +86,7 @@ SMART_APPEND_SLASH = True # not eorking as middleware different after Dj2.0 ROOT_URLCONF = "troggle.urls" LOGOUT_REDIRECT_URL = "/statistics" # see troggle/core/views/auth.py LOGIN_REDIRECT_URL = "/controlpanel" # see troggle/core/views/auth.py +PASSWORD_RESET_TIMEOUT = 3*60*60 # password reset sends an email. The response is valid for 3 hours SECURE_CONTENT_TYPE_NOSNIFF = True SECURE_BROWSER_XSS_FILTER = True @@ -97,7 +98,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # from Django 3.2 INSTALLED_APPS = ( "django.contrib.admin", - "django.contrib.auth", # includes the url redirections for login, logout + "django.contrib.auth", # includes the url redirections for login, logout, password_reset etc. "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", diff --git a/templates/login/register.html b/templates/login/register.html index 539306e..bc3fe81 100644 --- a/templates/login/register.html +++ b/templates/login/register.html @@ -64,10 +64,15 @@ So type in the same email address that you use there. <div class='align-right'> <input type="checkbox" checked name="visible" onclick="myFunction()">Make Passwords visible (on this form only) -<br /><br /> - <button class="fancybutton" style="padding: 0.5em 25px; font-size: 100%;" type = "submit" value = "Go to" > - Register → - </button> + <br /><br /> + <button class="fancybutton" style="padding: 0.5em 25px; font-size: 100%;" + onclick="window.location.href='/accounts/password_reset/'" value = "Go to" > + Reset password + </button> + + <button class="fancybutton" style="padding: 0.5em 25px; font-size: 100%;" type = "submit" > + Register → + </button> </div> </form> </div> @@ -53,7 +53,7 @@ from troggle.core.views.logbooks import ( ) from troggle.core.views.other import controlpanel, exportlogbook, frontpage, todos from troggle.core.views.prospect import prospecting -from troggle.core.views.user_registration import register +from troggle.core.views.user_registration import register, reset_done from troggle.core.views.scans import allscans, cavewallets, scansingle, walletslistperson, walletslistyear from troggle.core.views.signup import signup from troggle.core.views.uploads import dwgupload, expofilerename, gpxupload, photoupload @@ -93,7 +93,7 @@ todo = ''' # WHen running on the server, apache intercepts all the /expofiles/ files so troggle never sees them, # so the "content type" is set by whatever apache thinks it should be. Which means .gpx files -# get treated as XML and the web browser fails to do anything usefull +# get treated as XML and the web browser fails to do anything useful if settings.EXPOFILESREMOTE: expofilesurls = [ @@ -168,9 +168,10 @@ 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 line 109 in this file + path("accounts/register/<slug:username>", register, name="re_register"), # overriding django.contrib.auth.urls + path("accounts/register/", register, name="register"), # overriding django.contrib.auth.urls + path("accounts/reset/done/", reset_done, name="password_reset_done"), # overriding django.contrib.auth.urls + path('accounts/', include('django.contrib.auth.urls')), # see line 109 in this file NB initial "/accounts/" in URL path('person/<slug:slug>', person, name="person"), path('personexpedition/<slug:slug>/<int:year>', personexpedition, name="personexpedition"), |