mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2024-11-25 08:41:51 +00:00
New user login/logoff system using standard Dj
This commit is contained in:
parent
6d6bec35f2
commit
d1cd72c5f8
@ -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,7 +253,7 @@ 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',
|
||||||
|
58
core/views/auth.py
Normal file
58
core/views/auth.py
Normal 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', {})
|
||||||
|
|
||||||
|
|
@ -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():
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
|
||||||
|
@ -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
|
||||||
|
17
pre-push.sh
17
pre-push.sh
@ -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\""
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
@ -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',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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 %}
|
||||||
|
|
||||||
|
25
templates/errors/generic.html
Normal file
25
templates/errors/generic.html
Normal 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 %}
|
@ -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 %}
|
53
templates/login/index.html
Normal file
53
templates/login/index.html
Normal 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 →"></p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
51
templates/login/logout.html
Normal file
51
templates/login/logout.html
Normal 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 →">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -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 %}
|
|
@ -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>
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
[CUCC Expo] Activation email
|
|
55
templates/registration/logged_out.html
Normal file
55
templates/registration/logged_out.html
Normal 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 →">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
<form action="/accounts/login/" method="GET" accept-charset="utf-8">
|
||||||
|
<br /><input type="submit" value="Login →">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -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 %}
|
|
@ -1,4 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% block content %}
|
|
||||||
You have been logged out.
|
|
||||||
{% endblock %}
|
|
@ -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 %}
|
|
@ -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 %}
|
|
@ -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> </td>
|
|
||||||
<td><input type="submit" value="Register" /></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
{% endblock %}
|
|
22
urls.py
22
urls.py
@ -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.
|
||||||
|
|
||||||
@ -41,6 +43,17 @@ else:
|
|||||||
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,12 +63,13 @@ 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, ),
|
||||||
|
Loading…
Reference in New Issue
Block a user