Initial upload
authorMikael Frykholm <mikael@frykholm.com>
Mon, 14 May 2018 08:27:06 +0000 (10:27 +0200)
committerMikael Frykholm <mikael@frykholm.com>
Mon, 14 May 2018 08:27:06 +0000 (10:27 +0200)
25 files changed:
.gitignore [new file with mode: 0644]
customerportal/__init__.py [new file with mode: 0644]
customerportal/admin.py [new file with mode: 0644]
customerportal/apps.py [new file with mode: 0644]
customerportal/migrations/__init__.py [new file with mode: 0644]
customerportal/models.py [new file with mode: 0644]
customerportal/static/css/styles.css [new file with mode: 0644]
customerportal/templates/customerportal/landing.html [new file with mode: 0644]
customerportal/tests.py [new file with mode: 0644]
customerportal/urls.py [new file with mode: 0644]
customerportal/views.py [new file with mode: 0644]
manage.py [new file with mode: 0755]
templates/base_generic.html [new file with mode: 0644]
templates/registration/login.html [new file with mode: 0644]
templates/registration/logout.html [new file with mode: 0644]
templates/registration/password_reset_complete.hml [new file with mode: 0644]
templates/registration/password_reset_confirm.hml [new file with mode: 0644]
templates/registration/password_reset_done.hml [new file with mode: 0644]
templates/registration/password_reset_email.html [new file with mode: 0644]
templates/registration/password_reset_form.hml [new file with mode: 0644]
tranquillity/__init__.py [new file with mode: 0644]
tranquillity/auth_backend.py [new file with mode: 0644]
tranquillity/settings.py [new file with mode: 0644]
tranquillity/urls.py [new file with mode: 0644]
tranquillity/wsgi.py [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..27db8fc
--- /dev/null
@@ -0,0 +1,3 @@
+__pycache__/
+*.py[cod]
+
diff --git a/customerportal/__init__.py b/customerportal/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/customerportal/admin.py b/customerportal/admin.py
new file mode 100644 (file)
index 0000000..8c38f3f
--- /dev/null
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/customerportal/apps.py b/customerportal/apps.py
new file mode 100644 (file)
index 0000000..8b8fcbf
--- /dev/null
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class CustomerportalConfig(AppConfig):
+    name = 'customerportal'
diff --git a/customerportal/migrations/__init__.py b/customerportal/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/customerportal/models.py b/customerportal/models.py
new file mode 100644 (file)
index 0000000..71a8362
--- /dev/null
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/customerportal/static/css/styles.css b/customerportal/static/css/styles.css
new file mode 100644 (file)
index 0000000..53e0822
--- /dev/null
@@ -0,0 +1,5 @@
+.sidebar-nav {
+    margin-top: 20px;
+    padding: 0;
+    list-style: none;
+}
diff --git a/customerportal/templates/customerportal/landing.html b/customerportal/templates/customerportal/landing.html
new file mode 100644 (file)
index 0000000..7ac974b
--- /dev/null
@@ -0,0 +1,19 @@
+{% extends "base_generic.html" %}
+
+{% block content %}
+    <h1>Customer data</h1>
+
+    {% if bookinstance_list %}
+    <ul>
+
+      {% for bookinst in bookinstance_list %} 
+      <li class="{% if bookinst.is_overdue %}text-danger{% endif %}">
+        <a href="{% url 'book-detail' bookinst.book.pk %}">{{bookinst.book.title}}</a> ({{ bookinst.due_back }})        
+      </li>
+      {% endfor %}
+    </ul>
+
+    {% else %}
+      <p>There is not customer info right now.</p>
+    {% endif %}       
+{% endblock %}
diff --git a/customerportal/tests.py b/customerportal/tests.py
new file mode 100644 (file)
index 0000000..7ce503c
--- /dev/null
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/customerportal/urls.py b/customerportal/urls.py
new file mode 100644 (file)
index 0000000..88a9cac
--- /dev/null
@@ -0,0 +1,7 @@
+from django.urls import path
+
+from . import views
+
+urlpatterns = [
+    path('', views.index, name='index'),
+]
diff --git a/customerportal/views.py b/customerportal/views.py
new file mode 100644 (file)
index 0000000..3578d6a
--- /dev/null
@@ -0,0 +1,9 @@
+from django.shortcuts import render
+from django.http import HttpResponse
+from django.contrib.auth.decorators import login_required
+
+@login_required
+def index(request):
+
+    return render(request, 'customerportal/landing.html')
+
diff --git a/manage.py b/manage.py
new file mode 100755 (executable)
index 0000000..fff3de8
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tranquillity.settings")
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        ) from exc
+    execute_from_command_line(sys.argv)
diff --git a/templates/base_generic.html b/templates/base_generic.html
new file mode 100644 (file)
index 0000000..aadbb0d
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  
+  {% block title %}<title>Tranquillity</title>{% endblock %}
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+  
+  <!-- Add additional CSS in static file -->
+  {% load static %}
+  <link rel="stylesheet" href="{% static 'css/styles.css' %}">
+</head>
+
+<body>
+
+  <div class="container-fluid">
+
+    <div class="row">
+      <div class="col-sm-2">
+      {% block sidebar %}
+      <ul class="sidebar-nav">
+          <li><a href="{% url 'index' %}">Home</a></li>
+       {% if user.is_authenticated %}
+         <li>User: {{ user.get_username }}</li>
+         <li><a href="{% url 'logout'%}?next={{request.path}}">Logout</a></li>
+       {% else %}
+         <li><a href="{% url 'login'%}?next={{request.path}}">Login</a></li>
+       {% endif %}
+     </ul>
+     {% endblock %}
+      </div>
+      <div class="col-sm-10 ">
+      {% block content %}{% endblock %}
+      </div>
+    </div>
+
+  </div>
+</body>
+</html>
diff --git a/templates/registration/login.html b/templates/registration/login.html
new file mode 100644 (file)
index 0000000..3211a0d
--- /dev/null
@@ -0,0 +1,39 @@
+{% extends "base_generic.html" %}
+
+{% block content %}
+
+{% if form.errors %}
+<p>Your username and password didn't match. Please try again.</p>
+{% endif %}
+
+{% if next %}
+    {% if user.is_authenticated %}
+    <p>Your account doesn't have access to this page. To proceed,
+    please login with an account that has access.</p>
+    {% else %}
+    <p>Please login to see this page.</p>
+    {% endif %}
+{% endif %}
+
+<form method="post" action="{% url 'login' %}">
+{% csrf_token %}
+
+<div>
+  <td>{{ form.username.label_tag }}</td>
+  <td>{{ form.username }}</td>
+</div>
+<div>
+  <td>{{ form.password.label_tag }}</td>
+  <td>{{ form.password }}</td>
+</div>
+
+<div>
+  <input type="submit" value="login" />
+  <input type="hidden" name="next" value="{{ next }}" />
+</div>
+</form>
+
+{# Assumes you setup the password_reset view in your URLconf #}
+<p><a href="{% url 'password_reset' %}">Lost password?</a></p>
+
+{% endblock %}
diff --git a/templates/registration/logout.html b/templates/registration/logout.html
new file mode 100644 (file)
index 0000000..b7b3d6f
--- /dev/null
@@ -0,0 +1,7 @@
+{% extends "base_generic.html" %}
+
+{% block content %}
+<p>Logged out!</p>  
+
+<a href="{% url 'login'%}">Click here to login again.</a>
+{% endblock %}
diff --git a/templates/registration/password_reset_complete.hml b/templates/registration/password_reset_complete.hml
new file mode 100644 (file)
index 0000000..0f6b709
--- /dev/null
@@ -0,0 +1,7 @@
+{% extends "base_generic.html" %}
+{% block content %}
+
+<h1>The password has been changed!</h1>
+<p><a href="{% url 'login' %}">log in again?</a></p>
+
+{% endblock %}
diff --git a/templates/registration/password_reset_confirm.hml b/templates/registration/password_reset_confirm.hml
new file mode 100644 (file)
index 0000000..c088351
--- /dev/null
@@ -0,0 +1,33 @@
+{% extends "base_generic.html" %}
+
+{% block content %}
+
+    {% if validlink %}
+        <p>Please enter (and confirm) your new password.</p>
+        <form action="" method="post">
+            <div style="display:none">
+                <input type="hidden" value="{{ csrf_token }}" name="csrfmiddlewaretoken">
+            </div>
+            <table>
+                <tr>
+                    <td>{{ form.new_password1.errors }}
+                        <label for="id_new_password1">New password:</label></td>
+                    <td>{{ form.new_password1 }}</td>
+                </tr>
+                <tr>
+                    <td>{{ form.new_password2.errors }}
+                        <label for="id_new_password2">Confirm password:</label></td>
+                    <td>{{ form.new_password2 }}</td>
+                </tr>
+                <tr>
+                    <td></td>
+                    <td><input type="submit" value="Change my password" /></td>
+                </tr>
+            </table>
+        </form>
+    {% else %}
+        <h1>Password reset failed</h1>
+        <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p>
+    {% endif %}
+
+{% endblock %}
diff --git a/templates/registration/password_reset_done.hml b/templates/registration/password_reset_done.hml
new file mode 100644 (file)
index 0000000..bcad27d
--- /dev/null
@@ -0,0 +1,4 @@
+{% extends "base_generic.html" %}
+{% block content %}
+<p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p>
+{% endblock %}
diff --git a/templates/registration/password_reset_email.html b/templates/registration/password_reset_email.html
new file mode 100644 (file)
index 0000000..37467b8
--- /dev/null
@@ -0,0 +1,2 @@
+Someone asked for password reset for email {{ email }}. Follow the link below:
+{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
diff --git a/templates/registration/password_reset_form.hml b/templates/registration/password_reset_form.hml
new file mode 100644 (file)
index 0000000..c4082b9
--- /dev/null
@@ -0,0 +1,10 @@
+{% extends "base_generic.html" %}
+{% block content %}
+
+<form action="" method="post">{% csrf_token %}
+    {% if form.email.errors %} {{ form.email.errors }} {% endif %}
+        <p>{{ form.email }}</p> 
+    <input type="submit" class="btn btn-default btn-lg" value="Reset password" />
+</form>
+
+{% endblock %}
diff --git a/tranquillity/__init__.py b/tranquillity/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tranquillity/auth_backend.py b/tranquillity/auth_backend.py
new file mode 100644 (file)
index 0000000..44edaee
--- /dev/null
@@ -0,0 +1,14 @@
+from django.contrib.auth import get_user_model
+from django.contrib.auth.backends import ModelBackend
+
+class EmailBackend(ModelBackend):
+    def authenticate(self, username=None, password=None, **kwargs):
+        UserModel = get_user_model()
+        try:
+            user = UserModel.objects.get(email=username)
+        except UserModel.DoesNotExist:
+            return None
+        else:
+            if user.check_password(password):
+                return user
+        return None
diff --git a/tranquillity/settings.py b/tranquillity/settings.py
new file mode 100644 (file)
index 0000000..cc33677
--- /dev/null
@@ -0,0 +1,126 @@
+"""
+Django settings for tranquillity project.
+
+Generated by 'django-admin startproject' using Django 2.0.5.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/2.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/2.0/ref/settings/
+"""
+
+import os
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '2tgzkdah6pqa8(-etly^f$elbgao!3ey$vs$nbrhf3vm91_4z^'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'customerportal',
+]
+
+MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'tranquillity.urls'
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': ['./templates',],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'tranquillity.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+    }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/2.0/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/2.0/howto/static-files/
+
+STATIC_URL = '/static/'
+
+
+# Redirect to home URL after login (Default redirects to /accounts/profile/)
+LOGIN_REDIRECT_URL = '/'
+AUTHENTICATION_BACKENDS = ['tranquillity.auth_backend.EmailBackend']
diff --git a/tranquillity/urls.py b/tranquillity/urls.py
new file mode 100644 (file)
index 0000000..c6b6057
--- /dev/null
@@ -0,0 +1,32 @@
+"""tranquillity URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/2.0/topics/http/urls/
+Examples:
+Function views
+    1. Add an import:  from my_app import views
+    2. Add a URL to urlpatterns:  path('', views.home, name='home')
+Class-based views
+    1. Add an import:  from other_app.views import Home
+    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
+Including another URLconf
+    1. Import the include() function: from django.urls import include, path
+    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path, include
+
+urlpatterns = [
+    path('customerportal/', include('customerportal.urls')),
+    path('admin/', admin.site.urls),
+]
+
+#Add Django site authentication urls (for login, logout, password management)
+urlpatterns += [
+    path('accounts/', include('django.contrib.auth.urls')),
+]
+#Add URL maps to redirect the base URL to our application
+from django.views.generic import RedirectView
+urlpatterns += [
+    path('', RedirectView.as_view(url='/customerportal/')),
+]
diff --git a/tranquillity/wsgi.py b/tranquillity/wsgi.py
new file mode 100644 (file)
index 0000000..1a73c0c
--- /dev/null
@@ -0,0 +1,16 @@
+"""
+WSGI config for tranquillity project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tranquillity.settings")
+
+application = get_wsgi_application()