From 70df49c892ac017d0aef9f1361a665b08f2fedaf Mon Sep 17 00:00:00 2001 From: Christopher Charbonneau Wells Date: Wed, 16 Aug 2017 12:46:26 -0400 Subject: [PATCH] Add authentication and login handling for existing views. --- api/urls.py | 2 +- babyblotter/settings.py | 11 ++++ babyblotter/templates/admin/base_site.html | 9 ++++ babyblotter/templates/registration/base.html | 29 +++++++++++ babyblotter/templates/registration/login.html | 39 ++++++++++++++ .../registration/password_reset_complete.html | 11 ++++ .../registration/password_reset_confirm.html | 47 +++++++++++++++++ .../registration/password_reset_done.html | 15 ++++++ .../registration/password_reset_form.html | 31 +++++++++++ babyblotter/urls.py | 7 +++ core/templates/core/base.html | 4 +- core/urls.py | 2 +- core/views.py | 51 ++++++++++--------- 13 files changed, 229 insertions(+), 29 deletions(-) create mode 100644 babyblotter/templates/admin/base_site.html create mode 100644 babyblotter/templates/registration/base.html create mode 100644 babyblotter/templates/registration/login.html create mode 100644 babyblotter/templates/registration/password_reset_complete.html create mode 100644 babyblotter/templates/registration/password_reset_confirm.html create mode 100644 babyblotter/templates/registration/password_reset_done.html create mode 100644 babyblotter/templates/registration/password_reset_form.html diff --git a/api/urls.py b/api/urls.py index 8d27ae7c..97d8acd5 100644 --- a/api/urls.py +++ b/api/urls.py @@ -17,6 +17,6 @@ router.register(r'tummy-times', TummyTimeViewSet) urlpatterns = [ url(r'^api/', include(router.urls)), - url(r'^api-auth/', include('rest_framework.urls', + url(r'^api/auth/', include('rest_framework.urls', namespace='rest_framework')) ] diff --git a/babyblotter/settings.py b/babyblotter/settings.py index db87e45b..62c4b09a 100644 --- a/babyblotter/settings.py +++ b/babyblotter/settings.py @@ -20,6 +20,7 @@ ALLOWED_HOSTS = [] INSTALLED_APPS = [ 'api', + 'babyblotter', 'core', 'rest_framework', @@ -75,6 +76,16 @@ DATABASES = { } +# Authentication +# https://docs.djangoproject.com/en/1.11/topics/auth/default/ + +LOGIN_REDIRECT_URL = '/' + +LOGIN_URL = '/login/' + +LOGOUT_REDIRECT_URL = '/login/' + + # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ diff --git a/babyblotter/templates/admin/base_site.html b/babyblotter/templates/admin/base_site.html new file mode 100644 index 00000000..bdeeb981 --- /dev/null +++ b/babyblotter/templates/admin/base_site.html @@ -0,0 +1,9 @@ +{% extends "admin/base.html" %} + +{% block title %}{{ title }} | Baby Blotter Admin{% endblock %} + +{% block branding %} +

Baby Blotter Admin

+{% endblock %} + +{% block nav-global %}{% endblock %} diff --git a/babyblotter/templates/registration/base.html b/babyblotter/templates/registration/base.html new file mode 100644 index 00000000..28d4b22c --- /dev/null +++ b/babyblotter/templates/registration/base.html @@ -0,0 +1,29 @@ +{% load static widget_tweaks %} + + + + + + + {% block title %}{% endblock %} | Baby Blotter + + + + +
+
+

Baby Blotter

+
+
+ {% block content %}{% endblock %} +
+
+ + diff --git a/babyblotter/templates/registration/login.html b/babyblotter/templates/registration/login.html new file mode 100644 index 00000000..6d0d55c3 --- /dev/null +++ b/babyblotter/templates/registration/login.html @@ -0,0 +1,39 @@ +{% extends "registration/base.html" %} +{% load static widget_tweaks %} + +{% block title %}Login{% endblock %} +{% block content %} +
+ {% csrf_token %} + + + + +
+
+ +
+ {% render_field form.username name='username' class+='form-control' id='username-input-group' placeholder=form.username.label %} +
+ + +
+
+ +
+ {% render_field form.password name='password' class+='form-control' id='password-input-group' placeholder=form.password.label %} +
+ + +
+ +
+ Forgot your password? +
+{% endblock %} \ No newline at end of file diff --git a/babyblotter/templates/registration/password_reset_complete.html b/babyblotter/templates/registration/password_reset_complete.html new file mode 100644 index 00000000..0915f701 --- /dev/null +++ b/babyblotter/templates/registration/password_reset_complete.html @@ -0,0 +1,11 @@ +{% extends "registration/base.html" %} + +{% block title %}Password Reset Successfully!{% endblock %} +{% block content %} + +
+

Your password has been set. You may go ahead and log in now.

+

Log in

+
+ +{% endblock %} \ No newline at end of file diff --git a/babyblotter/templates/registration/password_reset_confirm.html b/babyblotter/templates/registration/password_reset_confirm.html new file mode 100644 index 00000000..ff989bd2 --- /dev/null +++ b/babyblotter/templates/registration/password_reset_confirm.html @@ -0,0 +1,47 @@ +{% extends "registration/base.html" %} +{% load static widget_tweaks %} + +{% block title %}Password Reset{% endblock %} +{% block content %} + +
+ {% csrf_token %} + + {% if form.errors %} +
+

Oh snap! The two passwords + did not match. Please try again.

+
+ {% endif %} + +
+

Enter your new password in each field below.

+
+ + +
+
+ +
+ {% render_field form.new_password1 name='new_password1' class+='form-control' id='password1-input-group' %} +
+ + + +
+
+ +
+ {% render_field form.new_password2 name='new_password2' class+='form-control' id='password2-input-group' %} +
+ + +
+ +{% endblock %} \ No newline at end of file diff --git a/babyblotter/templates/registration/password_reset_done.html b/babyblotter/templates/registration/password_reset_done.html new file mode 100644 index 00000000..c70e2f32 --- /dev/null +++ b/babyblotter/templates/registration/password_reset_done.html @@ -0,0 +1,15 @@ +{% extends "registration/base.html" %} + +{% block title %}Reset Email Sent{% endblock %} +{% block content %} + +
+

We've emailed you instructions for setting your + password, if an account exists with the email you entered. You + should receive them shortly.

+

If you don't receive an email, please make sure you've + entered the address you registered with, and check your spam + folder.

+
+ +{% endblock %} \ No newline at end of file diff --git a/babyblotter/templates/registration/password_reset_form.html b/babyblotter/templates/registration/password_reset_form.html new file mode 100644 index 00000000..2e09368d --- /dev/null +++ b/babyblotter/templates/registration/password_reset_form.html @@ -0,0 +1,31 @@ +{% extends "registration/base.html" %} +{% load static widget_tweaks %} + +{% block title %}Forgot Password{% endblock %} +{% block content %} + +
+

Enter your account email address in the form below. If + the address is valid, you will receive instructions for resetting your + password.

+
+ +
+ {% csrf_token %} + + +
+
+ +
+ {% render_field form.email name='email' class+='form-control' id='email-input-group' placeholder=form.email.label %} +
+ + +
+ +{% endblock %} \ No newline at end of file diff --git a/babyblotter/urls.py b/babyblotter/urls.py index 808f8cc6..ce7311f9 100644 --- a/babyblotter/urls.py +++ b/babyblotter/urls.py @@ -3,9 +3,16 @@ from __future__ import unicode_literals from django.conf.urls import url, include from django.contrib import admin +from django.contrib.auth import views urlpatterns = [ url(r'^admin/', admin.site.urls), + + url(r'^login/$', views.LoginView.as_view(), name='login'), + url(r'^logout/$', views.LogoutView.as_view(), name='logout'), + url('^password_reset/$', views.PasswordResetView.as_view(), + name='password_reset',), + url(r'', include('api.urls')), url(r'', include('core.urls')), ] diff --git a/core/templates/core/base.html b/core/templates/core/base.html index 93a707a6..d0d50312 100644 --- a/core/templates/core/base.html +++ b/core/templates/core/base.html @@ -27,7 +27,7 @@ -
+
{% block content %}{% endblock %}
diff --git a/core/urls.py b/core/urls.py index d8c56c10..21cf2d29 100644 --- a/core/urls.py +++ b/core/urls.py @@ -6,7 +6,7 @@ from django.conf.urls import url from . import views urlpatterns = [ - url(r'^$', views.Index.as_view(), name='index'), + url(r'^$', views.Dashboard.as_view(), name='index'), url(r'children/$', views.ChildList.as_view(), name='child-list'), url(r'children/add/$', views.ChildAdd.as_view(), name='child-add'), diff --git a/core/views.py b/core/views.py index b4d0991c..92dd1400 100644 --- a/core/views.py +++ b/core/views.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.base import TemplateView from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.generic.list import ListView @@ -8,131 +9,131 @@ from django.views.generic.list import ListView from .models import Child, DiaperChange, Feeding, Note, Sleep, TummyTime -class Index(TemplateView): +class Dashboard(LoginRequiredMixin, TemplateView): template_name = 'core/index.html' -class ChildList(ListView): +class ChildList(LoginRequiredMixin, ListView): model = Child -class ChildAdd(CreateView): +class ChildAdd(LoginRequiredMixin, CreateView): model = Child fields = ['first_name', 'last_name', 'birth_date'] success_url = '/children' -class ChildUpdate(UpdateView): +class ChildUpdate(LoginRequiredMixin, UpdateView): model = Child fields = ['first_name', 'last_name', 'birth_date'] success_url = '/children' -class ChildDelete(DeleteView): +class ChildDelete(LoginRequiredMixin, DeleteView): model = Child success_url = '/children' -class DiaperChangeList(ListView): +class DiaperChangeList(LoginRequiredMixin, ListView): model = DiaperChange -class DiaperChangeAdd(CreateView): +class DiaperChangeAdd(LoginRequiredMixin, CreateView): model = DiaperChange fields = ['child', 'time', 'wet', 'solid', 'color'] success_url = '/changes' -class DiaperChangeUpdate(UpdateView): +class DiaperChangeUpdate(LoginRequiredMixin, UpdateView): model = DiaperChange fields = ['child', 'time', 'wet', 'solid', 'color'] success_url = '/changes' -class DiaperChangeDelete(DeleteView): +class DiaperChangeDelete(LoginRequiredMixin, DeleteView): model = DiaperChange success_url = '/changes' -class FeedingList(ListView): +class FeedingList(LoginRequiredMixin, ListView): model = Feeding -class FeedingAdd(CreateView): +class FeedingAdd(LoginRequiredMixin, CreateView): model = Feeding fields = ['child', 'start', 'end', 'type', 'method'] success_url = '/feedings' -class FeedingUpdate(UpdateView): +class FeedingUpdate(LoginRequiredMixin, UpdateView): model = Feeding fields = ['child', 'start', 'end', 'type', 'method'] success_url = '/feedings' -class FeedingDelete(DeleteView): +class FeedingDelete(LoginRequiredMixin, DeleteView): model = Feeding success_url = '/feedings' -class NoteList(ListView): +class NoteList(LoginRequiredMixin, ListView): model = Note -class NoteAdd(CreateView): +class NoteAdd(LoginRequiredMixin, CreateView): model = Note fields = ['child', 'note'] success_url = '/notes' -class NoteUpdate(UpdateView): +class NoteUpdate(LoginRequiredMixin, UpdateView): model = Note fields = ['child', 'note'] success_url = '/notes' -class NoteDelete(DeleteView): +class NoteDelete(LoginRequiredMixin, DeleteView): model = Note success_url = '/notes' -class SleepList(ListView): +class SleepList(LoginRequiredMixin, ListView): model = Sleep -class SleepAdd(CreateView): +class SleepAdd(LoginRequiredMixin, CreateView): model = Sleep fields = ['child', 'start', 'end'] success_url = '/sleep' -class SleepUpdate(UpdateView): +class SleepUpdate(LoginRequiredMixin, UpdateView): model = Sleep fields = ['child', 'start', 'end'] success_url = '/sleep' -class SleepDelete(DeleteView): +class SleepDelete(LoginRequiredMixin, DeleteView): model = Sleep success_url = '/sleep' -class TummyTimeList(ListView): +class TummyTimeList(LoginRequiredMixin, ListView): model = TummyTime -class TummyTimeAdd(CreateView): +class TummyTimeAdd(LoginRequiredMixin, CreateView): model = TummyTime fields = ['child', 'start', 'end', 'milestone'] success_url = '/tummy-time' -class TummyTimeUpdate(UpdateView): +class TummyTimeUpdate(LoginRequiredMixin, UpdateView): model = TummyTime fields = ['child', 'start', 'end', 'milestone'] success_url = '/tummy-time' -class TummyTimeDelete(DeleteView): +class TummyTimeDelete(LoginRequiredMixin, DeleteView): model = TummyTime success_url = '/tummy-time'