mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2025-12-19 03:17:16 +00:00
password reset via encrypted token by email
This commit is contained in:
@@ -121,9 +121,10 @@ def controlpanel(request):
|
|||||||
jobs_completed = []
|
jobs_completed = []
|
||||||
|
|
||||||
def process_imports():
|
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("reinit",reinit_db)
|
||||||
jq.enq("caves",import_caves)
|
jq.enq("caves",import_caves)
|
||||||
|
jq.enq("users",import_users)
|
||||||
jq.enq("people",import_people)
|
jq.enq("people",import_people)
|
||||||
jq.enq("scans",import_surveyscans)
|
jq.enq("scans",import_surveyscans)
|
||||||
jq.enq("logbooks",import_logbooks)
|
jq.enq("logbooks",import_logbooks)
|
||||||
@@ -136,6 +137,7 @@ def controlpanel(request):
|
|||||||
jobs_completed.append("Caves")
|
jobs_completed.append("Caves")
|
||||||
if request.POST.get("import_people", False):
|
if request.POST.get("import_people", False):
|
||||||
import_people()
|
import_people()
|
||||||
|
|
||||||
jobs_completed.append("People")
|
jobs_completed.append("People")
|
||||||
if request.POST.get("import_surveyscans", False):
|
if request.POST.get("import_surveyscans", False):
|
||||||
import_surveyscans()
|
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.
|
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):
|
def lbeKey(lbe):
|
||||||
|
|||||||
@@ -23,7 +23,23 @@ todo = """
|
|||||||
- login automatically, and redirect to control panel ?
|
- 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):
|
def register(request, username=None):
|
||||||
"""To register a new user on the troggle system, similar to the "expo" user
|
"""To register a new user on the troggle system, similar to the "expo" user
|
||||||
(with cavey:beery password) but specific to an individual
|
(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})
|
# 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:
|
# 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)
|
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 ?
|
# to do, login automatically, and redirect to control panel ?
|
||||||
return HttpResponseRedirect("/accounts/login/")
|
return HttpResponseRedirect("/accounts/login/")
|
||||||
else:
|
else:
|
||||||
@@ -63,9 +79,12 @@ def register(request, username=None):
|
|||||||
|
|
||||||
return render(request, "login/register.html", {"form": form, "warning": warning})
|
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()
|
f = get_encryptor()
|
||||||
ru = []
|
ru = []
|
||||||
|
|
||||||
print(f"\n + Saving users, encrypted emails, and password hashes")
|
print(f"\n + Saving users, encrypted emails, and password hashes")
|
||||||
for u in User.objects.all():
|
for u in User.objects.all():
|
||||||
if u.username in ["expo", "expoadmin"]:
|
if u.username in ["expo", "expoadmin"]:
|
||||||
@@ -76,29 +95,32 @@ def save_users(request, updated_user, email):
|
|||||||
original = f.decrypt(e_email).decode()
|
original = f.decrypt(e_email).decode()
|
||||||
print(f" - {u.username} - {original}")
|
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
|
encryptedfile = settings.EXPOWEB / ENCRYPTED_DIR / USERS_FILE
|
||||||
try:
|
try:
|
||||||
print(f"- Rewriting the entire encrypted set of registered users to disc ")
|
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:
|
except:
|
||||||
message = f'! - Users encrypted data saving failed - \n!! Permissions failure ?! on attempting to save file "{encryptedfile}"'
|
message = f'! - Users encrypted data saving failed - \n!! Permissions failure ?! on attempting to save file "{encryptedfile}"'
|
||||||
print(message)
|
print(message)
|
||||||
|
raise
|
||||||
return render(request, "errors/generic.html", {"message": message})
|
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 }
|
jsondict = { "registered_users": registered_users }
|
||||||
try:
|
try:
|
||||||
if settings.DEVSERVER:
|
with open(encryptedfile, 'w', encoding='utf-8') as json_f:
|
||||||
with open(encryptedfile, 'w', encoding='utf-8') as json_f:
|
json.dump(jsondict, json_f, indent=1)
|
||||||
json.dump(jsondict, json_f, indent=1)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f" ! Exception dumping json <{e}>")
|
print(f" ! Exception dumping json <{e}>")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
commit_msg = f"Online (re-)registration of a troggle User"
|
commit_msg = f"Online (re-)registration of a troggle User"
|
||||||
editor = f"{updated_user.username} <{email}>"
|
|
||||||
try:
|
try:
|
||||||
add_commit(encryptedfile, commit_msg, editor)
|
add_commit(encryptedfile, commit_msg, git_string)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f" ! Exception doing git add/commit <{e}>")
|
print(f" ! Exception doing git add/commit <{e}>")
|
||||||
raise
|
raise
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ SMART_APPEND_SLASH = True # not eorking as middleware different after Dj2.0
|
|||||||
ROOT_URLCONF = "troggle.urls"
|
ROOT_URLCONF = "troggle.urls"
|
||||||
LOGOUT_REDIRECT_URL = "/statistics" # see troggle/core/views/auth.py
|
LOGOUT_REDIRECT_URL = "/statistics" # see troggle/core/views/auth.py
|
||||||
LOGIN_REDIRECT_URL = "/controlpanel" # 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_CONTENT_TYPE_NOSNIFF = True
|
||||||
SECURE_BROWSER_XSS_FILTER = True
|
SECURE_BROWSER_XSS_FILTER = True
|
||||||
@@ -97,7 +98,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # from Django 3.2
|
|||||||
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS = (
|
||||||
"django.contrib.admin",
|
"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.contenttypes",
|
||||||
"django.contrib.sessions",
|
"django.contrib.sessions",
|
||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
|
|||||||
@@ -64,10 +64,15 @@ So type in the same email address that you use there.
|
|||||||
<div class='align-right'>
|
<div class='align-right'>
|
||||||
<input type="checkbox" checked name="visible" onclick="myFunction()">Make Passwords visible (on this form only)
|
<input type="checkbox" checked name="visible" onclick="myFunction()">Make Passwords visible (on this form only)
|
||||||
|
|
||||||
<br /><br />
|
<br /><br />
|
||||||
<button class="fancybutton" style="padding: 0.5em 25px; font-size: 100%;" type = "submit" value = "Go to" >
|
<button class="fancybutton" style="padding: 0.5em 25px; font-size: 100%;"
|
||||||
Register →
|
onclick="window.location.href='/accounts/password_reset/'" value = "Go to" >
|
||||||
</button>
|
Reset password
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="fancybutton" style="padding: 0.5em 25px; font-size: 100%;" type = "submit" >
|
||||||
|
Register →
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
11
urls.py
11
urls.py
@@ -53,7 +53,7 @@ from troggle.core.views.logbooks import (
|
|||||||
)
|
)
|
||||||
from troggle.core.views.other import controlpanel, exportlogbook, frontpage, todos
|
from troggle.core.views.other import controlpanel, exportlogbook, frontpage, todos
|
||||||
from troggle.core.views.prospect import prospecting
|
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.scans import allscans, cavewallets, scansingle, walletslistperson, walletslistyear
|
||||||
from troggle.core.views.signup import signup
|
from troggle.core.views.signup import signup
|
||||||
from troggle.core.views.uploads import dwgupload, expofilerename, gpxupload, photoupload
|
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,
|
# 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
|
# 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:
|
if settings.EXPOFILESREMOTE:
|
||||||
expofilesurls = [
|
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
|
# 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/<slug:username>", register, name="re_register"), # overriding django.contrib.auth.urls
|
||||||
path("accounts/register/", register, name="register"),
|
path("accounts/register/", register, name="register"), # overriding django.contrib.auth.urls
|
||||||
path('accounts/', include('django.contrib.auth.urls')), # see line 109 in this file
|
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('person/<slug:slug>', person, name="person"),
|
||||||
path('personexpedition/<slug:slug>/<int:year>', personexpedition, name="personexpedition"),
|
path('personexpedition/<slug:slug>/<int:year>', personexpedition, name="personexpedition"),
|
||||||
|
|||||||
Reference in New Issue
Block a user