New user login/logoff system using standard Dj

This commit is contained in:
Philip Sargent 2021-04-06 00:49:09 +01:00
parent 6d6bec35f2
commit d1cd72c5f8
25 changed files with 348 additions and 197 deletions

View File

@ -126,18 +126,12 @@ class PageTests(TestCase):
def test_expoweb_dir(self): def test_expoweb_dir(self):
response = self.client.get('/handbook') response = self.client.get('/handbook')
content = response.content.decode() content = response.content.decode()
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 302) # directory, so redirects to /index.htm
ph = r'Introduction to expo'
phmatch = re.search(ph, content)
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'")
def test_expoweb_dirslash(self): def test_expoweb_dirslash(self):
response = self.client.get('/handbook/') response = self.client.get('/handbook/')
content = response.content.decode() content = response.content.decode()
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 302) # directory, so redirects to /index.htm
ph = r'Introduction to expo'
phmatch = re.search(ph, content)
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'")
def test_expoweb_dir_no_index(self): def test_expoweb_dir_no_index(self):
response = self.client.get('/handbook/troggle') response = self.client.get('/handbook/troggle')
@ -147,6 +141,31 @@ class PageTests(TestCase):
phmatch = re.search(ph, content) phmatch = re.search(ph, content)
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'") self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'")
def test_expoweb_dir_with_index_htm(self):
response = self.client.get('/years/1999/index.htm')
content = response.content.decode()
self.assertEqual(response.status_code, 200) # directory, so redirects to /index.htm
ph = r'Passage descriptions for 1999'
phmatch = re.search(ph, content)
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'")
def test_expoweb_dir_with_index_html(self):
response = self.client.get('/years/2015/index.html')
content = response.content.decode()
self.assertEqual(response.status_code, 200) # directory, so redirects to /index.htm
ph = r'Things left at top camp 2014'
phmatch = re.search(ph, content)
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'")
def test_expoweb_dir_with_index2(self):
response = self.client.get('/handbook/index.htm')
content = response.content.decode()
self.assertEqual(response.status_code, 200)
ph = r'Introduction to expo'
phmatch = re.search(ph, content)
#print("\n ! - test_expoweb_dir_with_index2\n{}\n{}".format(response.reason_phrase, content))
self.assertIsNotNone(phmatch, "Failed to find expected text: '" + ph +"'")
def test_expoweb_htm(self): def test_expoweb_htm(self):
response = self.client.get('/handbook/index.htm') response = self.client.get('/handbook/index.htm')
content = response.content.decode() content = response.content.decode()
@ -234,9 +253,9 @@ class PageTests(TestCase):
def test_page_folk(self): def test_page_folk(self):
# This page is separately generated, so it has the full data content # This page is separately generated, so it has the full data content
response = self.client.get('/folk/') response = self.client.get('/folk/index.htm')
content = response.content.decode() content = response.content.decode()
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
for ph in [ r'involves some active contribution', for ph in [ r'involves some active contribution',
r'Naomi Griffiths', r'Naomi Griffiths',
r'Gail Smith', r'Gail Smith',

58
core/views/auth.py Normal file
View File

@ -0,0 +1,58 @@
from builtins import str
from django.shortcuts import render
from django.http import Http404, HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth import forms as auth_forms
# This is copied from CUYC.cuy.website.view.auth
# If we want to do the whole online-email thing, we would also need to copy across the code in these
# imported files and delete what is superfluous.
# Or we could just load the latest version of django-registration app.
#from cuy.club.models import Member, Message
#from ..forms import WebsiteLoginForm, WebsiteRegisterForm
#from ...common import mail_site_error
#from .generic import user_is_active
'''The login and logout functions.
This is also where we would manage registration: for people wanting to create and validate their individual
logon accounts/forgottenpassword'''
############################
# Authentication Functions #
############################
def expologout(request):
login_form = auth_forms.AuthenticationForm()
logout(request)
return render(request, 'login/logout.html', {'form':login_form})
def expologin(request):
# GET
if not request.method == 'POST':
if (not request.user.is_authenticated) or (not request.user.is_active):
return render(request, 'login/index.html', {})
else:
# going to login page when you are already logged in
return render(request, 'tasks.html', {})
# POST
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is None:
return render(request, 'login/index.html',
{'invalid': True, 'username':username})
if not user.is_active:
return render(request, 'login/enable.html',
{'login_state':'notenabled'})
try:
login(request, user)
# Should do the ?next= stuff here..
return render(request, 'tasks.html', {})
except:
return render(request, 'errors/generic.html', {})

View File

@ -35,8 +35,8 @@ def showrequest(request):
return HttpResponse(request.GET) return HttpResponse(request.GET)
def frontpage(request): def frontpage(request):
'''never seen in practice''' '''never seen in common practice. Logon should redirect here when this is more useful'''
# bthe messages system does a popup on this page if there is a recent message, e.g. from the admin site actions. # the messages system does a popup on this page if there is a recent message, e.g. from the admin site actions.
# via django.contrib.messages.middleware.MessageMiddleware # via django.contrib.messages.middleware.MessageMiddleware
# this is set in the templates. # this is set in the templates.
if request.user.is_authenticated(): if request.user.is_authenticated():

View File

@ -6,7 +6,6 @@ import json
import resource import resource
import settings import settings
import credentials
""" Command-line utility for loading cave data files into troggle's database. """ Command-line utility for loading cave data files into troggle's database.
The command line options select which combination of classes of data will be imported, The command line options select which combination of classes of data will be imported,
@ -56,9 +55,13 @@ if os.geteuid() == 0:
exit() exit()
expouser=settings.EXPOUSER expouser=settings.EXPOUSER
expouserpass=credentials.EXPOUSERPASS expouserpass=settings.EXPOUSERPASS
expouseremail=settings.EXPOUSER_EMAIL expouseremail=settings.EXPOUSER_EMAIL
expoadminuser=settings.EXPOADMINUSER
expoadminuserpass=settings.EXPOADMINUSERPASS
expoadminuseremail=settings.EXPOADMINUSER_EMAIL
def reinit_db(): def reinit_db():
"""Rebuild database from scratch. Deletes the file first if sqlite is used, """Rebuild database from scratch. Deletes the file first if sqlite is used,
otherwise it drops the database and creates it. otherwise it drops the database and creates it.
@ -109,9 +112,28 @@ def reinit_db():
print("users in db already: ",len(User.objects.all())) print("users in db already: ",len(User.objects.all()))
with transaction.atomic(): with transaction.atomic():
try: try:
print(" - Setting up admin user on: " + django.db.connections.databases['default']['NAME']) print(" - Setting up expo user on: " + django.db.connections.databases['default']['NAME'])
print(" - user: {} ({:.5}...) <{}> ".format(expouser, expouserpass, expouseremail)) print(" - user: {} ({:.5}...) <{}> ".format(expouser, expouserpass, expouseremail))
user = User.objects.create_user(expouser, expouseremail, expouserpass) user = User.objects.create_user(expouser, expouseremail, expouserpass)
user.is_staff = False
user.is_superuser = False
user.save()
except:
print(" ! INTEGRITY ERROR user on: " + settings.DATABASES['default']['NAME'])
print(django.db.connections.databases['default']['NAME'])
print(" ! You probably have not got a clean db when you thought you had.\n")
print(" ! Also you are probably NOT running an in-memory db now.\n")
print("users in db: ",len(User.objects.all()))
print("tables in db: ",len(connection.introspection.table_names()))
memdumpsql(fn='integrityfail.sql')
django.db.connections.databases['default']['NAME'] = ':memory:'
#raise
with transaction.atomic():
try:
print(" - Setting up expoadmin user on: " + django.db.connections.databases['default']['NAME'])
print(" - user: {} ({:.5}...) <{}> ".format(expoadminuser, expoadminuserpass, expoadminuseremail))
user = User.objects.create_user(expoadminuser, expoadminuseremail, expoadminuserpass)
user.is_staff = True user.is_staff = True
user.is_superuser = True user.is_superuser = True
user.save() user.save()

View File

@ -4,9 +4,3 @@
from collections import Counter, Iterator, Mapping, OrderedDict from collections import Counter, Iterator, Mapping, OrderedDict
/mnt/d/CUCC-Expo/t37/lib/python3.7/site-packages/django/core/paginator.py:126: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working /mnt/d/CUCC-Expo/t37/lib/python3.7/site-packages/django/core/paginator.py:126: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working
class Page(collections.Sequence): class Page(collections.Sequence):
/mnt/d/CUCC-Expo/t37/lib/python3.7/site-packages/registration/auth_urls_classes.py:20: DeprecationWarning:
include('registration.auth_urls') is deprecated and will be
removed in django-registration 3.0. Use
include('django.contrib.auth.urls') instead.
DeprecationWarning

View File

@ -14,6 +14,8 @@ a system-wide location rather than just a local directory.
This file is included at the end of the main troggle/settings.py file so that This file is included at the end of the main troggle/settings.py file so that
it overwrites defaults in that file. it overwrites defaults in that file.
Read https://adamj.eu/tech/2020/03/16/use-pathlib-in-your-django-project/
""" """
print(" * importing troggle/localsettings.py") print(" * importing troggle/localsettings.py")
@ -24,11 +26,11 @@ print(" * importing troggle/localsettings.py")
# - we don't want to have to change the expo system password ! # - we don't want to have to change the expo system password !
#----------------------------------------------------------------- #-----------------------------------------------------------------
# default values, real secrets imported from credentials.py # default values, real secrets imported from credentials.py
# EXPOUSERPASS = "nnn:gggggg"
# EMAIL_HOST_PASSWORD = "insert-real-email-password-here"
from credentials import EXPOUSERPASS
from credentials import EMAIL_HOST_PASSWORD
SECRET_KEY = "z514d%crn*fpd*ewt_27m_r^a#vaeozn0---^fj!355qki*vj2"
EXPOUSERPASS = "161:gosser"
EXPOADMINUSERPASS = "gosser:161"
EMAIL_HOST_PASSWORD = "smtp-django-test"
EXPOFILESREMOTE = False # if True, then re-routes urls in expofiles to remote sever. Tests are then less accurate. EXPOFILESREMOTE = False # if True, then re-routes urls in expofiles to remote sever. Tests are then less accurate.
#SECURE_SSL_REDIRECT = True # breaks 7 tests in test suite 301 not 200 (or 302) and runserver fails completely #SECURE_SSL_REDIRECT = True # breaks 7 tests in test suite 301 not 200 (or 302) and runserver fails completely
@ -127,11 +129,13 @@ TEMPLATES = [
] ]
# Passwords are loaded from credentials.py by settings.py # Passwords are loaded from credentials.py by settings.py
EXPOUSERPASS = "nnn:gggggg" # overwritten by loading from credentials.py #EXPOUSERPASS = "nnn:gggggg" # overwritten by loading from credentials.py
EMAIL_HOST_PASSWORD = "insert-real-email-password-here" # overwritten by loading from credentials.py #EMAIL_HOST_PASSWORD = "insert-real-email-password-here" # overwritten by loading from credentials.py
EXPOUSER = 'expo' EXPOUSER = 'expo'
EXPOUSER_EMAIL = 'philip.sargent@gmail.com' EXPOUSER_EMAIL = 'philip.sargent@gmail.com'
EXPOADMINUSER = 'expoadmin'
EXPOADMINUSER_EMAIL = 'philip.sargent@gmail.com'
EMAIL_HOST = "smtp-auth.mythic-beasts.com" EMAIL_HOST = "smtp-auth.mythic-beasts.com"
EMAIL_HOST_USER = "django-test@klebos.net" # Philip Sargent really EMAIL_HOST_USER = "django-test@klebos.net" # Philip Sargent really

View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# create and sanitise files for pushing to repo # create and sanitise files for pushing to repo
# Philip Sargent 2020/06/20 # Philip Sargent 2021/04/06
echo deprecations. echo deprecations.
python -Wall manage.py check -v 3 2>deprecations.txt >/dev/null python -Wall manage.py check -v 3 2>deprecations.txt >/dev/null
echo diffsettings. echo diffsettings.
@ -13,14 +13,17 @@ python manage.py inspectdb > troggle-inspectdb.py
#egrep -in "unable|error" troggle-inspectdb.py #egrep -in "unable|error" troggle-inspectdb.py
echo remove passwords. echo remove passwords.
cp localsettings.py localsettingsWSL.py cp localsettings.py localsettingsWSL.py
sed -i '/EXPOUSERPASS/ s/^.*$/EXPOUSERPASS = "nnn:gggggg - real-expo-password--is-imported-from-credentials.py"/' diffsettings.txt sed -i '/EXPOUSERPASS/ s/^.*$/EXPOUSERPASS = "nnn:gggggg - real-expo-password---imported-from-localsettings.py"/' diffsettings.txt
echo " reset: EXPOUSERPASS = \"nnn:gggggg\" - real-expo-password--is-imported-from-credentials.py" echo " reset: EXPOUSERPASS = \"nnn:gggggg\" - real-expo-password---imported-from-localsettings.py"
sed -i '/EMAIL_HOST_PASSWORD/ s/^.*$/EMAIL_HOST_PASSWORD = "real-email-password--is-imported-from-credentials.py"/' diffsettings.txt sed -i '/EXPOADMINUSERPASS/ s/^.*$/EXPOADMINUSERPASS = "nnn:gggggg - real-expo-password---imported-from-localsettings.py"/' diffsettings.txt
echo " reset: EMAIL_HOST_PASSWORD = \"real-email-password-is-imported-from-credentials.py\"" echo " reset: EXPOUSERPASS = \"gggggg:nnn\" - real-expo-password---imported-from-localsettings.py"
sed -i '/SECRET_KEY/ s/^.*$/SECRET_KEY = "real-SECRET_KEY-is-imported-from-credentials.py"/' diffsettings.txt sed -i '/EMAIL_HOST_PASSWORD/ s/^.*$/EMAIL_HOST_PASSWORD = "real-email-password---imported-from-localsettings.py"/' diffsettings.txt
echo " reset: SECRET_KEY = \"real-SECRET_KEY-is-imported-from-credentials.py\"" echo " reset: EMAIL_HOST_PASSWORD = \"real-email-password--imported-from-localsettings.py\""
sed -i '/SECRET_KEY/ s/^.*$/SECRET_KEY = "real-SECRET_KEY--imported-from-localsettings.py"/' diffsettings.txt
echo " reset: SECRET_KEY = \"real-SECRET_KEY--imported-from-localsettings.py\""
# #

View File

@ -1,7 +1,7 @@
confusable-homoglyphs==3.2.0 confusable-homoglyphs==3.2.0
Django==1.11.29 Django==1.11.29
django-registration==2.5.2
docutils==0.16 docutils==0.16
gunicorn==20.1.0
Pillow==7.2.0 Pillow==7.2.0
pytz==2020.1 pytz==2020.1
Unidecode==1.1.1 Unidecode==1.1.1

View File

@ -23,7 +23,6 @@ print("* importing troggle/settings.py")
# default value, then gets overwritten by real secrets # default value, then gets overwritten by real secrets
SECRET_KEY = "not-the-real-secret-key-a#vaeozn0---^fj!355qki*vj2" SECRET_KEY = "not-the-real-secret-key-a#vaeozn0---^fj!355qki*vj2"
from credentials import SECRET_KEY
# Note that this builds upon the django system installed # Note that this builds upon the django system installed
# global settings in # global settings in
@ -123,7 +122,7 @@ INSTALLED_APPS = (
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.admindocs', 'django.contrib.admindocs',
# 'django.contrib.staticfiles', # Using workarounds with expopages # 'django.contrib.staticfiles', # Using workarounds with expopages
'registration', # only for expo user. REPLACE using django.contrib.auth #'registration', # only for expo user. REPLACE using django.contrib.auth
'troggle.core', 'troggle.core',
) )

View File

@ -20,7 +20,7 @@
You are logged in as {{ user.username }} You are logged in as {{ user.username }}
{% if user.person %}(<a href="{{ user.person.get_absolute_url }}">{{ user.person }}</a>) {% if user.person %}(<a href="{{ user.person.get_absolute_url }}">{{ user.person }}</a>)
{% endif %}. {% endif %}.
| <a href="{% url "auth_logout" %}">Log out</a> {% else %} <a href='/accounts/logout'>Sign up</a> | <a href='{% url "auth_login" %}'>Log in</a> {% endif %} | <a <a href='/accounts/logout/'>Log out</a> {% else %} <a href='/accounts/register/'>Register</a> | <a href='/accounts/login/'>Log in</a> {% endif %}
{% endblock%} {% endblock%}
{% block editLink %} {% block editLink %}

View File

@ -0,0 +1,25 @@
{% extends 'base.html' %}
{% block title %}Website Error - {% endblock %}
{% block content %}
<div class='middle'>
<h2>Website Error</h2>
</div>
<div style='width: 300px;' class='middle3 login'>
<div class='align-center'>
<div class='space'></div>
<div class='align-center'>
<h3>There has been an error.</h3>
<p>We are terribly sorry but an unknown fault has occurred. </p>
</div>
</div>
</div>
{% endblock %}

View File

@ -33,25 +33,25 @@
{% block content %} {% block content %}
<div id="col1"> <div id="col1">
<h3>Welcome</h3> <h3>Welcome</h3>
<p class="indent"> <p class="indent">
This is Troggle, the online system for Cambridge University Caving Club's Expeditions to Austria. This is <b>Troggle</b>, the online system for Cambridge University Caving Club's Expeditions to Austria.
</p> </p>
<p class="indent"> <p class="indent">
Here you will find information about the {{expedition.objects.count}} expeditions the club has undertaken since 1976. Browse survey information, photos, and description wikis for {{Cave.objects.count}} caves, {{subcave.objects.count}} areas within those caves, and {{extantqms.count}} going leads yet to be explored. We have {{Photo.objects.count}} photos and {{Logbookentry.objects.count}} logbook entries. Here you will find information about the {{expedition.objects.count}} expeditions the club has undertaken since 1976. Browse survey information, photos, and description pages for {{Cave.objects.count}} caves and {{extantqms.count}} going leads yet to be explored. We have {{Photo.objects.count}} photos and {{Logbookentry.objects.count}} logbook entries.
</p> </p>
<p class="indent"> <p class="indent">
You are not logged-in, so not all the pages will be visible and you will not be able to edit anything. <!-- logged in users are directed to 'tasks.html' not this 'frontpage.html' -->
You are not logged-in, so a few of the unpublished cave survey pages will not be visible to you. And of course you will not be able to edit anything.
</p> </p>
<!-- <img src="/expofiles/photos/2007/selected/eishoehle5nial.jpg">-->
<img src="/expofiles/photos/2007/selected/eishoehle4nial.jpg">
<p>Nial in <a href="/expofiles/photos/2007/selected/">Eishohle in 2007</a>.
{% endblock content %} {% endblock content %}
{% block margins %} {% block margins %}
<img src="{{ settings.MEDIA_URL }}eieshole.jpg">
<img src="{{ settings.MEDIA_URL }}goesser.jpg">
{% endblock margins %} {% endblock margins %}

View File

@ -0,0 +1,53 @@
{% extends 'base.html' %}
{% block content %}
<!-- To understand how this all works, with invisible default behaviour, see
troggle/templates/login/logout.html
troggle/templates/registration/
because magic
This is because Django is Opinionated and does lots of Invisible Defaults
-->
<div class='middle'>
<h2>Troggle user login</h2>
</div>
{% if message %}
<div style='width: 350px;' class='middle3 login'>
{% if title %}
<div class='align-center'>
<h3>{{title}}</h3>
<div class='space'></div>
{% endif %}
<p>{{message }}</p>
</div>
{% endif %}
<h3>Troggle ordinary user login - no access to Django control panel</h3>
<p>(This is using template login/index.html)
<div style='width: 250px;' class='middle3 login'>
<div class='align-center'>
<div class='space'></div>
{% if invalid %}
<p class='error'>The username and password you provided don't match. Please try again.</p>
<p>Have you <a href='/accounts/forgottenpassword/'>forgotten your password</a>?<br/>
Or perhaps <a href='/accounts/forgottenusername/'>your username</a>?</p>
<p>Neither of those links work yet, by the way, I'm only trying to *appear* helpful.
<div class='space'></div>
{% endif %}
<div class='align-center'>
<form action="" method="post" accept-charset="utf-8">{% csrf_token %}
<table class='form'>
<tr><th><label for="id_username">Username:</label></th><td><input id="id_username" type="text" name="username" maxlength="30" /></td></tr>
<tr><th><label for="id_password">Password:</label></th><td><input type="password" name="password" id="id_password" /></td></tr>
</table>
<div class='space'></div>
<br/>
<p><input type="submit" value="Login &rarr;"></p>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,51 @@
{% extends 'base.html' %}
{% block content %}
<!-- this overrides the django.contrib.auth default logout form
and it must be placed in
troggle/templates/login/logout.html
because magic
Note that we need to have TWO DIFFERENT logout templates to make this work,
the other one is in
troggle/templates/registration/
That one is for logging out of the Django Admin system.
This one is for logging out of the normal system whereas this one
Not forgetting the template in
troggle/templates/login/index
which also has a login form.
This is because Django is Opinionated and does lots of Invisible Defaults
-->
<div class='middle'>
<h2>You have been logged out</h2>
</div>
<h3>Troggle ordinary user login - no access to Django control panel</h3>
<p>(using template login/logout.html)
<div style='width: 250px;' class='middle3 login'>
<div class='align-center'>
<div class='space'></div>
<div class='align-center'>
<form action="/login/" method="post" accept-charset="utf-8">{% csrf_token %}
<table class='form'>
{{form.as_table}}
</table>
<div class='space'></div>
<span class='indent'>
<br /><input type="submit" value="Login &rarr;">
</form>
</div>
</form>
</div>
</div>
{% endblock %}

View File

@ -1,25 +0,0 @@
{% extends "base.html" %}
{% block title %}
New troggle account registered
{% endblock %}
{% block header %}
<h1>activate.html</h1>
{% endblock %}
{% block content %}
{% if account %}
<p>
Hello, {{ account }}! Your account is now activated. Now you can <a href="{%url "auth_login"%}">log in</a> with the password you chose. Use the links in the upper right to control this in the future.
</p>
<p>
If you have been on the expedition in the past, you already have a profile in the system; <a href={% url "profiles_select_profile" %}>click here </a> to find it and link it to your account. Otherwise, please <a href={% url "profiles_create_profile" %}> create yourself a new profile</a>.
</p>
{% else %}
The activation key you entered has already been used or was invalid.
{% endif %}
{% endblock %}

View File

@ -1,10 +0,0 @@
<P>Hello {{ form.user }},</P>
<P>Glad you're joining the CUCC EXPO team! Please go to</P>
<P><a href="{{ site }}{% url "registration_activate" activation_key %}">{{ site }}{% url "registration_activate" activation_key %}</a></P>
<P>to activate your account. Do this within {{ expiration_days }} days, or else you'll have to sign up again.</P>
<P>Yours,<BR>
The magical troggle</P>

View File

@ -1,10 +0,0 @@
Hello {{ form.user }},
Glad you're joining the CUCC EXPO team! Please go to
{{ site }}{% url "registration_activate" activation_key %}
to activate your account. Do this within {{ expiration_days }} days, or else you'll have to sign up again.
Yours,
The magical troggle

View File

@ -1 +0,0 @@
[CUCC Expo] Activation email

View File

@ -0,0 +1,55 @@
{% extends 'base.html' %}
{% block content %}
<!-- this overrides the django.contrib.admin default logout form
and it must be placed in
troggle/templates/registration/
because magic
Note that we need to have TWO DIFFERENT logout templates to make this work,
the other one is in
troggle/templates/login/logout.html
That one is for logging out
of the normal system whereas this one is for logging out of the Django Admin system.
Not forgetting the template in
troggle/templates/login/index
which also has a login form.
This is because Django is Opinionated and does lots of Invisible Defaults
-->
<div class='middle'>
<h2>You have been logged out</h2>
</div>
<!-- Yeah this logon form sometimes fails to appear, and then the Submit button gives a horrible crash.
All because of some CSRF horribleness ? Possibly.
So let's not even attempt to have it here, OK?
-->
<!--
<h3>Troggle user Login</h3>
<p>(using template registration/logged_out.html)
<div style='width: 250px;' class='middle3 login'>
<div class='align-center'>
<div class='space'></div>
<div class='align-center'>
<form action="/login/" method="post" accept-charset="utf-8">{% csrf_token %}
<table class='form'>
{{form.as_table}}
</table>
<div class='space'></div>
<span class='indent'>
<br /><input type="submit" value="Login &rarr;">
</form>
</div>
-->
<form action="/accounts/login/" method="GET" accept-charset="utf-8">
<br /><input type="submit" value="Login &rarr;">
</form>
{% endblock %}

View File

@ -1,27 +0,0 @@
{% extends "base.html" %}
{% load csrffaker %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<div align="center">
<pre>This uses the registration/login.html template</pre>
<form method="post" action=".">{% csrf_token %}
<table>
<tr><td>{{ form.username.label_tag }}</td><td>{{ form.username }}</td></tr>
<tr><td>{{ form.password.label_tag }}</td><td>{{ form.password }}</td></tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
</div>
{% endblock %}

View File

@ -1,4 +0,0 @@
{% extends "base.html" %}
{% block content %}
You have been logged out.
{% endblock %}

View File

@ -1,6 +0,0 @@
{% extends “base.html” %}
{% block body %}
Hello {{ account }}!
Check your email to confirm the activation. There are {{ expiration_days }} days left to do it.
{% endblock %}

View File

@ -1,13 +0,0 @@
{% extends "base.html" %}
{% block title %}
{{ block.super }}: registration complete
{% endblock %}
{% block contentheader %}
<h1>Registration Complete</h1>
{% endblock %}
{% block content %}
<p>Thank you for signing up. An email with the activation code has been sent to your inbox. </p>
{% endblock %}

View File

@ -1,50 +0,0 @@
{% extends "base.html" %}
{% block title %}
registration_form.html | {{ block.super }}
{% endblock %}
{% block header %}
<h1>registration_form.html</h1>
{% endblock %}
{% block content %}
<form action="{% url "registration_register" %}" method="POST">{% csrf_token %}
{% for error in form.non_field_errors %}
<span style="color:red">{{ error }}</span>
{% endfor %}
<table>
<tr>
<td align="right" valign="top">Username:</td>
<td>
{{ form.username }} <br/>
{% for error in form.username.errors %}
<span style="color:red">{{ error }}</span>
{% endfor %}
</td>
</tr>
<tr>
<td align="right" valign="top">Email:</td>
<td>
{{ form.email }} <br/>
{% for error in form.email.errors %}
<span style="color:red">{{ error }}</span>
{% endfor %}
</td>
</tr>
<tr>
<td align="right" valign="top">Password:</td>
<td>
{{ form.password1 }} <br/>
{% for error in form.password1.errors %}
<span style="color:red">{{ error }}</span>
{% endfor %}
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type="submit" value="Register" /></td>
</tr>
</table>
</form>
{% endblock %}

24
urls.py
View File

@ -4,6 +4,7 @@ from django.views.generic.base import RedirectView
from django.views.generic.edit import UpdateView from django.views.generic.edit import UpdateView
from django.views.generic.list import ListView from django.views.generic.list import ListView
from django.contrib import admin from django.contrib import admin
from django.contrib import auth
from django.urls import reverse, resolve from django.urls import reverse, resolve
from troggle.core.views import surveys, logbooks, other, caves, statistics, survex from troggle.core.views import surveys, logbooks, other, caves, statistics, survex
@ -12,6 +13,7 @@ from troggle.core.views.caves import ent, prospecting_image, cavepage
from troggle.core.views.statistics import pathsreport, stats from troggle.core.views.statistics import pathsreport, stats
from troggle.core.views.expo import expofiles_redirect, expofilessingle, expopage, editexpopage, mediapage from troggle.core.views.expo import expofiles_redirect, expofilessingle, expopage, editexpopage, mediapage
from troggle.core.views.survex import survexcaveslist, survexcavesingle, svx from troggle.core.views.survex import survexcaveslist, survexcavesingle, svx
from troggle.core.views.auth import expologin, expologout
"""This sets the actualurlpatterns[] and urlpatterns[] lists which django uses """This sets the actualurlpatterns[] and urlpatterns[] lists which django uses
to resolve urls - in both directions as these are declarative. to resolve urls - in both directions as these are declarative.
@ -40,6 +42,17 @@ else:
expofilesurls = [ expofilesurls = [
url(r'^(?P<filepath>.*)$', expofilessingle, name="single"), # local copy of EXPOFILES url(r'^(?P<filepath>.*)$', expofilessingle, name="single"), # local copy of EXPOFILES
] ]
# The URLs provided by include('django.contrib.auth.urls') are:
# accounts/login/ [name='login']
# accounts/logout/ [name='logout']
# accounts/password_change/ [name='password_change']
# accounts/password_change/done/ [name='password_change_done']
# accounts/password_reset/ [name='password_reset']
# accounts/password_reset/done/ [name='password_reset_done']
# accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
# accounts/reset/done/ [name='password_reset_complete']
trogglepatterns = [ trogglepatterns = [
url(r'^expofiles/', include(expofilesurls)), url(r'^expofiles/', include(expofilesurls)),
@ -50,13 +63,14 @@ trogglepatterns = [
url(r'^people/?$', logbooks.personindex, name="personindex"), url(r'^people/?$', logbooks.personindex, name="personindex"),
url(r'^admin/doc/', include('django.contrib.admindocs.urls')), # needs docutils Python module (http://docutils.sf.net/). url(r'^admin/doc/', include('django.contrib.admindocs.urls')), # needs docutils Python module (http://docutils.sf.net/).
url(r'^admin/', admin.site.urls), url(r'^admin/', admin.site.urls), # includes admin login & logout urls
# setting LOGIN_URL = '/accounts/login/' is default # setting LOGIN_URL = '/accounts/login/' is default
#url(r'^accounts/', include('registration.backends.default.urls')), # deprecated, replace with .model_activation.urls # url ENDS WITH this string
url(r'^accounts/', include('registration.backends.model_activation.urls')), # deprecated in Dj3.0, but must not be commented out. url(r'logout/$', expologout, name='expologout'), # higher precedence than /accounts/logout
url(r'^accounts/', include('django.contrib.auth.urls')), # from Dj3.0, see site-packages\registration\auth_urls_classes.py url(r'login/$', expologin, name='expologin'), # higher precedence than /accounts/login
#url(r'^accounts/', include('django.contrib.auth.urls')), # from Dj3.0, see site-packages\registration\auth_urls_classes.py
url(r'^newqmnumber/?$', other.ajax_QM_number, ), url(r'^newqmnumber/?$', other.ajax_QM_number, ),
# url(r'^lbo_suggestions/?$', logbook_entry_suggestions), #broken, removed. # url(r'^lbo_suggestions/?$', logbook_entry_suggestions), #broken, removed.