add django-registration-redux and use some of it

for the moment this is for the password change url used in the auth
dropdown, and a better login page, but this might become other stuff
eventually too. the signup page exists and is linked to, even if i don't
have a great reason for this to exist

bunch of templates added now to support the intentional and
unintentional stuff
This commit is contained in:
Brian S. Stephan 2016-03-30 15:36:56 -05:00
parent e52f4c915f
commit 5225d2bd6b
24 changed files with 521 additions and 316 deletions

View File

@ -0,0 +1,14 @@
"""Site processors to add additional template tags and whatnot."""
from django.contrib.sites.shortcuts import get_current_site
from django.utils.functional import SimpleLazyObject
def site(request):
site = SimpleLazyObject(lambda: get_current_site(request))
protocol = 'https' if request.is_secure() else 'http'
return {
'site': site,
'site_root': SimpleLazyObject(lambda: "{0}://{1}".format(protocol, site.domain)),
}

View File

@ -11,6 +11,8 @@ https://docs.djangoproject.com/en/1.6/ref/settings/
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
from django.core.urlresolvers import reverse_lazy
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
@ -38,6 +40,7 @@ INSTALLED_APPS = (
'django.contrib.sites',
'django_extensions',
'adminplus',
'registration',
'rest_framework',
'countdown',
'dispatch',
@ -76,6 +79,7 @@ TEMPLATES = [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'dr_botzo.context_processors.site',
],
},
},
@ -132,6 +136,16 @@ REST_FRAMEWORK = {
}
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = BASE_DIR
# registration
LOGIN_REDIRECT_URL = reverse_lazy('index')
ACCOUNT_ACTIVATION_DAYS = 7
REGISTRATION_AUTO_LOGIN = True
# IRC bot stuff
# tuple of hostname, port number, and password (or None)

View File

@ -13,5 +13,6 @@ urlpatterns = patterns('',
url(r'^markov/', include('markov.urls')),
url(r'^races/', include('races.urls')),
url(r'^accounts/', include('registration.backends.default.urls')),
url(r'^admin/', include(admin.site.urls)),
)

View File

@ -1,323 +1,11 @@
* {
margin: 0;
padding: 0;
}
html, body {
font-family: "Helvetica", "Arial", sans-serif;
font-family: "Oxygen", "Helvetica", "Arial", sans-serif;
color: #333333;
background: #EFEFEF;
background: #FAFAFA;
height: 100%;
}
a:link, a:visited, a:hover, a:active {
color: #333333;
}
table {
padding: 5px;
}
#mainwrapper {
min-height: 100%;
position: relative;
width: 900px;
margin-left: auto;
margin-right: auto;
}
#header {
color: white;
background: #811610;
font-size: 11pt;
padding: 5px 10px;
border-left: 1px solid #CCCCCC;
border-right: 1px solid #CCCCCC;
}
#header a:link, #header a:visited, #header a:hover, #header a:active {
color: white;
text-decoration: none;
}
#header ul {
list-style-type: none;
margin: 0;
padding: 0;
}
#header li {
display: inline;
}
#header #subnav {
float: right;
}
#messages {
background: #EFEFEF;
border: 1px solid #BBBBBB;
width: 50%;
margin-left: auto;
margin-right: auto;
padding: 10px;
padding-left: 20px;
margin-bottom: 50px;
}
#messages ul {
list-style-type: none;
padding-left: 10px;
}
#messages .debug {
color: cyan;
}
#messages .info {
color: black;
}
#messages .success {
color: green;
}
#messages .warning {
color: orange;
}
#messages .error {
color: red;
}
#body {
background: white;
font-size: 11pt;
padding-top: 20px;
padding-bottom: 50px;
border-left: 1px solid #CCCCCC;
border-right: 1px solid #CCCCCC;
}
#loginform {
background: #EFEFEF;
width: 50%;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
padding: 10px;
border: 1px solid #BBBBBB;
}
#content {
margin-left: 25px;
margin-right: 25px;
line-height: 150%;
padding: 0 25px;
padding-top: 75px;
}
#content h1, #content h2, #content h3, #content h4, #content h5, #content h6 {
color: #811610;
margin-top: 25px;
margin-bottom: 25px;
clear: both;
}
#content p, #content ul, #content ol {
margin-bottom: 20px;
}
#content hr {
margin-top: 10px;
margin-bottom: 10px;
}
#content blockquote {
margin: 5px;
padding: 5px;
margin-left: 20px;
border: 1px solid #e0e0e0;
}
#content .journal-entry {
margin-bottom: 20px;
}
#content .unpub-warning {
color: red;
}
#content .entry-header a:link,
#content .entry-header a:visited,
#content .entry-header a:hover,
#content .entry-header a:active {
color: #811610;
text-decoration: none;
}
#content .entry-sep {
width: 30%;
margin-left: auto;
margin-right: auto;
border-top: 1px solid #e0e0e0;
margin-top: 35px;
margin-bottom: 50px;
}
#content ol, #content ul {
margin-left: 20px;
}
#content hr {
width: 50%;
margin-top: 25px;
margin-bottom: 25px;
margin-left: auto;
margin-right: auto;
color: #CCCCCC;
}
#actions {
margin-left: 100px;
margin-right: 100px;
}
div.actions {
margin-bottom: 50px;
}
div.actionblock {
margin-top: 10px;
padding: 5px;
}
div.actionform {
margin-top: 10px;
}
#editform #id_title, #editform #id_tag_str {
width: 75%;
}
.submission table th {
text-align: right;
}
.errorlist {
border: 1px solid red;
background: #FF8888;
margin-bottom: 5px;
}
.journal-entry .entry-header {
margin-bottom: 0px;
}
.journal-entry .entry-header h1 {
font-size: 24pt;
}
.journal-entry .entry-body {
clear: both;
padding: 5px;
}
.journal-entry .entry-subheader {
font-size: 9pt;
padding: 5px 5px 5px 25px;
position: relative;
top: -5px;
}
.journal-entry .entry-footer {
font-size: 8pt;
color: #888888;
padding: 5px 5px 5px 0;
}
.journal-entry .entry-footer a:link,
.journal-entry .entry-footer a:visited,
.journal-entry .entry-footer a:hover,
.journal-entry .entry-footer a:active {
font-size: 8pt;
color: #888888;
}
#pagination {
background: white;
width: 60%;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.page-previous {
margin-right: 15px;
}
.page-next {
margin-left: 15px;
}
.article-image-left {
float: left;
margin: 10px;
margin-top: 0;
margin-left: 0;
}
.article-image-right {
float: right;
margin: 10px;
margin-top: 0;
margin-right: 0;
}
.px400 {
width: 400px;
height: auto;
}
.shadow {
box-shadow: 2px 2px 3px #aaaaaa;
}
.thumbnail-image {
width: 150px;
height: auto;
margin: 5px;
}
#footer {
width: 100%;
height: 25px;
background: #EFEFEF;
padding: 10px 0;
border-top: 1px solid #BBBBBB;
font-size: 9pt;
color: #666666;
text-align: center;
}
#footer p {
margin-bottom: 0;
}
#footer a:link, #footer a:visited, #footer a:hover, #footer a:active {
color: #666666;
}
/*
vi:tabstop=4:expandtab:autoindent
*/

View File

@ -0,0 +1,44 @@
.registration_wrap form {
margin-left: 10%;
margin-right: 10%;
clear: both;
}
.registration_wrap label {
display: inline-block;
width: 30%;
}
.registration_wrap input[type="text"],
.registration_wrap input[type="email"],
.registration_wrap input[type="password"] {
width: 100%;
}
.registration_wrap .helptext {
color: #888888;
font-size: 0.75em;
display: block;
}
.registration_wrap input[type="submit"] {
line-height: 350px;
width: 25%;
}
.registration_wrap .errorlist,
.registration_wrap .errorlist li {
background: none;
color: red;
display: inline;
border: none;
margin-left: 0 !important;
}
.registration_wrap .extra {
clear: both;
margin-top: 100px;
text-align: center;
margin-left: auto;
margin-right: auto;
}

View File

@ -0,0 +1,16 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block registration_content %}
<p>{% trans "Account activation failed." %}</p>
{% endblock %}
{% comment %}
**registration/activate.html**
Used if account activation fails. With the default setup, has the following context:
``activation_key``
The activation key used during the activation attempt.
{% endcomment %}

View File

@ -0,0 +1,22 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block title %}{% trans "Account Activated" %}{% endblock %}
{% block registration_content %}
<p>
{% trans "Your account is now activated." %}
{% if not user.is_authenticated %}
{% trans "You can log in." %}
{% endif %}
</p>
{% endblock %}
{% comment %}
**registration/activation_complete.html**
Used after successful account activation. This template has no context
variables of its own, and should simply inform the user that their
account is now active.
{% endcomment %}

View File

@ -0,0 +1,77 @@
{% load i18n %}
{% load url from future %}
<!doctype html>
<html lang="en">
<head>
<title>{{ site.name }} {% trans "registration" %}</title>
</head>
<body>
<p>
{% blocktrans with site_name=site.name %}
You (or someone pretending to be you) have asked to register an account at
{{ site_name }}. If this wasn't you, please ignore this email
and your address will be removed from our records.
{% endblocktrans %}
</p>
<p>
{% blocktrans %}
To activate this account, please click the following link within the next
{{ expiration_days }} days:
{% endblocktrans %}
</p>
<p>
<a href="http://{{site.domain}}{% url 'registration_activate' activation_key %}">
{{site.domain}}{% url 'registration_activate' activation_key %}
</a>
</p>
<p>
{% blocktrans with site_name=site.name %}
Sincerely,
{{ site_name }} Management
{% endblocktrans %}
</p>
</body>
</html>
{% comment %}
**registration/activation_email.html**
Used to generate the html body of the activation email. Should display a
link the user can click to activate the account. This template has the
following context:
``activation_key``
The activation key for the new account.
``expiration_days``
The number of days remaining during which the account may be
activated.
``site``
An object representing the site on which the user registered;
depending on whether ``django.contrib.sites`` is installed, this
may be an instance of either ``django.contrib.sites.models.Site``
(if the sites application is installed) or
``django.contrib.sites.models.RequestSite`` (if not). Consult `the
documentation for the Django sites framework
<http://docs.djangoproject.com/en/dev/ref/contrib/sites/>`_ for
details regarding these objects' interfaces.
``user``
The new user account
``request``
``HttpRequest`` instance for better flexibility.
For example it can be used to compute absolute register URL:
http{% if request.is_secure %}s{% endif %}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
or when using Django >= 1.7:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
{% endcomment %}

View File

@ -0,0 +1,57 @@
{% load i18n %}
{% load url from future %}
{% blocktrans with site_name=site.name %}
You (or someone pretending to be you) have asked to register an account at
{{ site_name }}. If this wasn't you, please ignore this email
and your address will be removed from our records.
{% endblocktrans %}
{% blocktrans %}
To activate this account, please click the following link within the next
{{ expiration_days }} days:
{% endblocktrans %}
http://{{site.domain}}{% url 'registration_activate' activation_key %}
{% blocktrans with site_name=site.name %}
Sincerely,
{{ site_name }} Management
{% endblocktrans %}
{% comment %}
**registration/activation_email.txt**
Used to generate the text body of the activation email. Should display a
link the user can click to activate the account. This template has the
following context:
``activation_key``
The activation key for the new account.
``expiration_days``
The number of days remaining during which the account may be
activated.
``site``
An object representing the site on which the user registered;
depending on whether ``django.contrib.sites`` is installed, this
may be an instance of either ``django.contrib.sites.models.Site``
(if the sites application is installed) or
``django.contrib.sites.models.RequestSite`` (if not). Consult `the
documentation for the Django sites framework
<http://docs.djangoproject.com/en/dev/ref/contrib/sites/>`_ for
details regarding these objects' interfaces.
``user``
The new user account
``request``
``HttpRequest`` instance for better flexibility.
For example it can be used to compute absolute register URL:
http{% if request.is_secure %}s{% endif %}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
or when using Django >= 1.7:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
{% endcomment %}

View File

@ -0,0 +1,28 @@
{% load i18n %}{% trans "Account activation on" %} {{ site.name }}
{% comment %}
**registration/activation_email_subject.txt**
Used to generate the subject line of the activation email. Because the
subject line of an email must be a single line of text, any output
from this template will be forcibly condensed to a single line before
being used. This template has the following context:
``activation_key``
The activation key for the new account.
``expiration_days``
The number of days remaining during which the account may be
activated.
``site``
An object representing the site on which the user registered;
depending on whether ``django.contrib.sites`` is installed, this
may be an instance of either ``django.contrib.sites.models.Site``
(if the sites application is installed) or
``django.contrib.sites.models.RequestSite`` (if not). Consult `the
documentation for the Django sites framework
<http://docs.djangoproject.com/en/dev/ref/contrib/sites/>`_ for
details regarding these objects' interfaces.
{% endcomment %}

View File

@ -0,0 +1,47 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{% trans "Log in" %}{% endblock %}
{% block registration_content %}
<form role="form" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<input type="hidden" name="next" value="{{ next }}" />
{% buttons submit='Log In' reset='Cancel' layout='horizontal' %}{% endbuttons %}
</form>
<div class="extra">
<p>{% trans "Forgot your password?" %} <a href="{% url 'auth_password_reset' %}">{% trans "Reset it" %}</a>.
{% trans "Not a member?" %} <a href="{% url 'registration_register' %}">{% trans "Register" %}</a>.</p>
</div>
{% endblock %}
{% comment %}
**registration/login.html**
It's your responsibility to provide the login form in a template called
registration/login.html by default. This template gets passed four
template context variables:
``form``
A Form object representing the login form. See the forms
documentation for more on Form objects.
``next``
The URL to redirect to after successful login. This may contain a
query string, too.
``site``
The current Site, according to the SITE_ID setting. If you don't
have the site framework installed, this will be set to an instance
of RequestSite, which derives the site name and domain from the
current HttpRequest.
``site_name``
An alias for site.name. If you don't have the site framework
installed, this will be set to the value of
request.META['SERVER_NAME']. For more on sites, see The
"sites" framework.
{% endcomment %}

View File

@ -0,0 +1,8 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block title %}{% trans "Logged out" %}{% endblock %}
{% block registration_content %}
<p>{% trans "Successfully logged out" %}.</p>
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block title %}{% trans "Password changed" %}{% endblock %}
{% block registration_content %}
<p>{% trans "Password successfully changed!" %}</p>
{% endblock %}
{# This is used by django.contrib.auth #}

View File

@ -0,0 +1,17 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{% trans "Change password" %}{% endblock %}
{% block registration_content %}
<form role="form" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<input type="hidden" name="next" value="{{ next }}" />
{% buttons submit='Change Password' reset='Cancel' layout='horizontal' %}{% endbuttons %}
</form>
{% endblock %}
{# This is used by django.contrib.auth #}

View File

@ -0,0 +1,14 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block title %}{% trans "Password reset complete" %}{% endblock %}
{% block registration_content %}
<p>
{% trans "Your password has been reset!" %}
{% trans "You may now" %} <a href="{{ login_url }}">{% trans "log in" %}</a>.
</p>
{% endblock %}
{# This is used by django.contrib.auth #}

View File

@ -0,0 +1,18 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{% trans "Confirm password reset" %}{% endblock %}
{% block registration_content %}
<p>{% trans "Enter your new password below to reset your password:" %}</p>
<form role="form" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<input type="hidden" name="next" value="{{ next }}" />
{% buttons submit='Set Password' reset='Cancel' layout='horizontal' %}{% endbuttons %}
</form>
{% endblock %}
{# This is used by django.contrib.auth #}

View File

@ -0,0 +1,16 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block title %}{% trans "Password reset" %}{% endblock %}
{% block registration_content %}
<p>
{% blocktrans %}
We have sent you an email with a link to reset your password. Please check
your email and click the link to continue.
{% endblocktrans %}
</p>
{% endblock %}
{# This is used by django.contrib.auth #}

View File

@ -0,0 +1,26 @@
{% load i18n %}
{% load url from future %}
{% blocktrans %}Greetings{% endblocktrans %} {% if user.get_full_name %}{{ user.get_full_name }}{% else %}{{ user }}{% endif %},
{% blocktrans %}
You are receiving this email because you (or someone pretending to be you)
requested that your password be reset on the {{ domain }} site. If you do not
wish to reset your password, please ignore this message.
{% endblocktrans %}
{% blocktrans %}
To reset your password, please click the following link, or copy and paste it
into your web browser:
{% endblocktrans %}
{{ protocol }}://{{ domain }}{% url 'auth_password_reset_confirm' uid token %}
{% blocktrans %}Your username, in case you've forgotten:{% endblocktrans %} {{ user.username }}
{% blocktrans %}Best regards{% endblocktrans %},
{{ site_name }} {% blocktrans %}Management{% endblocktrans %}
{# This is used by django.contrib.auth #}

View File

@ -0,0 +1,18 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{% trans "Reset password" %}{% endblock %}
{% block registration_content %}
<p>Forgot your password? Enter your email in the form below and we'll send you instructions for creating a new one.</p>
<form role="form" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<input type="hidden" name="next" value="{{ next }}" />
{% buttons submit='Reset' reset='Cancel' layout='horizontal' %}{% endbuttons %}
</form>
{% endblock %}
{# This is used by django.contrib.auth #}

View File

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block extra_media %}{% load static %}
<link href="{% get_static_prefix %}css/registration.css" rel="stylesheet" type='text/css' />
{% endblock %}
{% block navbarbrand %}
<a class="navbar-brand navbar-brand-active" href="{% url 'home' %}">{{ site.domain }}</a>
{% endblock %}
{% block content %}
<div class="registration_wrap">
{% block registration_content %}{% endblock %}
</div>
{% endblock %}

View File

@ -0,0 +1,8 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block title %}{% trans "Registration is closed" %}{% endblock %}
{% block registration_content %}
<p>{% trans "Sorry, but registration is closed at this moment. Come back later." %}</p>
{% endblock %}

View File

@ -0,0 +1,18 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% block title %}{% trans "Activation email sent" %}{% endblock %}
{% block registration_content %}
<p>{% trans "Please check your email to complete the registration process." %}</p>
{% endblock %}
{% comment %}
**registration/registration_complete.html**
Used after successful completion of the registration form. This
template has no context variables of its own, and should simply inform
the user that an email containing account-activation information has
been sent.
{% endcomment %}

View File

@ -0,0 +1,27 @@
{% extends "registration/registration_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{% trans "Register for an account" %}{% endblock %}
{% block registration_content %}
<form role="form" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<input type="hidden" name="next" value="{{ next }}" />
{% buttons submit='Sign Up' reset='Cancel' layout='horizontal' %}{% endbuttons %}
</form>
{% endblock %}
{% comment %}
**registration/registration_form.html**
Used to show the form users will fill out to register. By default, has
the following context:
``form``
The registration form. This will be an instance of some subclass
of ``django.forms.Form``; consult `Django's forms documentation
<http://docs.djangoproject.com/en/dev/topics/forms/>`_ for
information on how to display this in a template.
{% endcomment %}

View File

@ -6,6 +6,7 @@ Django==1.8.8
django-adminplus==0.3
django-extensions==1.5.3
django-filter==0.10.0
django-registration-redux==1.4
djangorestframework==3.1.3
dodgy==0.1.7
futures==3.0.3