From bd017079d5ad9a48c0edffb8d8e02498a10fa34b Mon Sep 17 00:00:00 2001
From: Daoud Clarke
Date: Tue, 24 Oct 2023 10:32:06 +0100
Subject: [PATCH] Add login using allauth
---
mwmbl/settings_bg_prod.py | 2 +-
mwmbl/settings_common.py | 16 +++
mwmbl/settings_dev.py | 4 +-
mwmbl/templates/base.html | 22 ++++
mwmbl/templates/home.html | 5 +
mwmbl/templates/profile.html | 8 ++
mwmbl/templates/registration/login.html | 26 ++++
mwmbl/templates/signup.html | 10 ++
mwmbl/urls.py | 14 ++-
mwmbl/views.py | 24 ++++
poetry.lock | 158 +++++++++++++++++++++++-
pyproject.toml | 1 +
12 files changed, 285 insertions(+), 5 deletions(-)
create mode 100644 mwmbl/templates/base.html
create mode 100644 mwmbl/templates/home.html
create mode 100644 mwmbl/templates/profile.html
create mode 100644 mwmbl/templates/registration/login.html
create mode 100644 mwmbl/templates/signup.html
create mode 100644 mwmbl/views.py
diff --git a/mwmbl/settings_bg_prod.py b/mwmbl/settings_bg_prod.py
index 070bbf9..51d035e 100644
--- a/mwmbl/settings_bg_prod.py
+++ b/mwmbl/settings_bg_prod.py
@@ -5,4 +5,4 @@ ALLOWED_HOSTS = ["api.mwmbl.org", "mwmbl.org"]
DATA_PATH = "/app/storage"
RUN_BACKGROUND_PROCESSES = True
-NUM_PAGES = 10240000
+NUM_PAGES = 10240000
\ No newline at end of file
diff --git a/mwmbl/settings_common.py b/mwmbl/settings_common.py
index 645ebd4..14a1e5a 100644
--- a/mwmbl/settings_common.py
+++ b/mwmbl/settings_common.py
@@ -33,6 +33,10 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'mwmbl',
+
+ 'allauth',
+ 'allauth.account',
+ 'allauth.socialaccount',
]
MIDDLEWARE = [
@@ -43,6 +47,8 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
+
+ "allauth.account.middleware.AccountMiddleware",
]
ROOT_URLCONF = 'mwmbl.urls'
@@ -120,3 +126,13 @@ print("Static files", STATICFILES_DIRS)
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+AUTHENTICATION_BACKENDS = [
+ # Needed to login by username in Django admin, regardless of `allauth`
+ 'django.contrib.auth.backends.ModelBackend',
+
+ # `allauth` specific authentication methods, such as login by email
+ 'allauth.account.auth_backends.AuthenticationBackend',
+]
+
+ACCOUNT_EMAIL_REQUIRED = True
+ACCOUNT_EMAIL_VERIFICATION = "mandatory"
diff --git a/mwmbl/settings_dev.py b/mwmbl/settings_dev.py
index ee82351..c7cd281 100644
--- a/mwmbl/settings_dev.py
+++ b/mwmbl/settings_dev.py
@@ -3,7 +3,9 @@ from mwmbl.settings_common import *
DEBUG = True
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]
+EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+
DATA_PATH = "./devdata"
-RUN_BACKGROUND_PROCESSES = True
+RUN_BACKGROUND_PROCESSES = False
NUM_PAGES = 2560
diff --git a/mwmbl/templates/base.html b/mwmbl/templates/base.html
new file mode 100644
index 0000000..b397195
--- /dev/null
+++ b/mwmbl/templates/base.html
@@ -0,0 +1,22 @@
+
+
+
+
+ {% block title %}Simple is Better Than Complex{% endblock %}
+
+
+
+ My Site
+ {% if user.is_authenticated %}
+ logout
+ {% else %}
+ login / signup
+ {% endif %}
+
+
+
+ {% block content %}
+ {% endblock %}
+
+
+
diff --git a/mwmbl/templates/home.html b/mwmbl/templates/home.html
new file mode 100644
index 0000000..ed59579
--- /dev/null
+++ b/mwmbl/templates/home.html
@@ -0,0 +1,5 @@
+{% extends 'base.html' %}
+
+{% block content %}
+ Welcome, {{ user.username }}!
+{% endblock %}
diff --git a/mwmbl/templates/profile.html b/mwmbl/templates/profile.html
new file mode 100644
index 0000000..2923d40
--- /dev/null
+++ b/mwmbl/templates/profile.html
@@ -0,0 +1,8 @@
+{% extends "base.html" %}
+{% block title %}Profile Page{% endblock title %}
+{% block content %}
+
+
This is the profile page for {{user.username}}
+
+
+{% endblock content %}
diff --git a/mwmbl/templates/registration/login.html b/mwmbl/templates/registration/login.html
new file mode 100644
index 0000000..a5f87a3
--- /dev/null
+++ b/mwmbl/templates/registration/login.html
@@ -0,0 +1,26 @@
+{% extends 'base.html' %}
+
+{% block content %}
+ Log in to My Site
+ {% if form.errors %}
+ Your username and password didn't match. Please try again.
+ {% endif %}
+
+ {% endfor %}
+
+ New to My Site? Sign up
+
+{% endblock %}
diff --git a/mwmbl/templates/signup.html b/mwmbl/templates/signup.html
new file mode 100644
index 0000000..b858ff6
--- /dev/null
+++ b/mwmbl/templates/signup.html
@@ -0,0 +1,10 @@
+{% extends 'base.html' %}
+
+{% block content %}
+ Sign up
+
+{% endblock %}
diff --git a/mwmbl/urls.py b/mwmbl/urls.py
index 7d8bff6..b416085 100644
--- a/mwmbl/urls.py
+++ b/mwmbl/urls.py
@@ -15,12 +15,22 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
-from django.urls import path
+from django.contrib.auth import login, logout
+from django.template.defaulttags import url
+from django.urls import path, include
from mwmbl.api import api_original as api, api_v1
+from mwmbl.views import signup, profile
urlpatterns = [
path('admin/', admin.site.urls),
path('', api.urls),
- path('api/v1/', api_v1.urls)
+ path('api/v1/', api_v1.urls),
+ path('accounts/', include('allauth.urls')),
+
+ # path("accounts/", include("django.contrib.auth.urls")),
+ # path('accounts/new/', signup, name='signup'),
+ path('accounts/profile/', profile, name='profile'),
+ # path('login/', login, {'template_name': 'login.html'}, name='login'),
+ # path('logout/', logout, {'next_page': 'login'}, name='logout'),
]
diff --git a/mwmbl/views.py b/mwmbl/views.py
new file mode 100644
index 0000000..0ae3ba8
--- /dev/null
+++ b/mwmbl/views.py
@@ -0,0 +1,24 @@
+from django.contrib.auth import authenticate, login
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.forms import UserCreationForm
+from django.shortcuts import redirect, render
+
+
+def signup(request):
+ if request.method == 'POST':
+ form = UserCreationForm(request.POST)
+ if form.is_valid():
+ form.save()
+ username = form.cleaned_data.get('username')
+ raw_password = form.cleaned_data.get('password1')
+ user = authenticate(username=username, password=raw_password)
+ login(request, user)
+ return redirect('/')
+ else:
+ form = UserCreationForm()
+ return render(request, 'signup.html', {'form': form})
+
+
+@login_required
+def profile(request):
+ return render(request, 'profile.html')
diff --git a/poetry.lock b/poetry.lock
index d7a0647..f4395b2 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -419,6 +419,52 @@ files = [
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
+[[package]]
+name = "cryptography"
+version = "41.0.4"
+description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839"},
+ {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f"},
+ {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714"},
+ {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb"},
+ {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13"},
+ {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143"},
+ {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397"},
+ {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860"},
+ {file = "cryptography-41.0.4-cp37-abi3-win32.whl", hash = "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd"},
+ {file = "cryptography-41.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d"},
+ {file = "cryptography-41.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67"},
+ {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e"},
+ {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829"},
+ {file = "cryptography-41.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca"},
+ {file = "cryptography-41.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d"},
+ {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac"},
+ {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9"},
+ {file = "cryptography-41.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"},
+ {file = "cryptography-41.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91"},
+ {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8"},
+ {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6"},
+ {file = "cryptography-41.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311"},
+ {file = "cryptography-41.0.4.tar.gz", hash = "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a"},
+]
+
+[package.dependencies]
+cffi = ">=1.12"
+
+[package.extras]
+docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
+docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
+nox = ["nox"]
+pep8test = ["black", "check-sdist", "mypy", "ruff"]
+sdist = ["build"]
+ssh = ["bcrypt (>=3.1.5)"]
+test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
+test-randomorder = ["pytest-randomly"]
+
[[package]]
name = "cymem"
version = "2.0.8"
@@ -462,6 +508,18 @@ files = [
{file = "cymem-2.0.8.tar.gz", hash = "sha256:8fb09d222e21dcf1c7e907dc85cf74501d4cea6c4ed4ac6c9e016f98fb59cbbf"},
]
+[[package]]
+name = "defusedxml"
+version = "0.7.1"
+description = "XML bomb protection for Python stdlib modules"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
+ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
+]
+
[[package]]
name = "django"
version = "4.2.6"
@@ -483,6 +541,28 @@ tzdata = {version = "*", markers = "sys_platform == \"win32\""}
argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"]
+[[package]]
+name = "django-allauth"
+version = "0.57.0"
+description = "Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "django-allauth-0.57.0.tar.gz", hash = "sha256:a095ef0db7de305d9175772c78e765ebd5fceb004ae61c1383d7fc1af0f7c5b1"},
+]
+
+[package.dependencies]
+Django = ">=3.2"
+pyjwt = {version = ">=1.7", extras = ["crypto"]}
+python3-openid = ">=3.0.8"
+requests = ">=2.0.0"
+requests-oauthlib = ">=0.3.0"
+
+[package.extras]
+mfa = ["qrcode (>=7.0.0)"]
+saml = ["python3-saml (>=1.15.0,<2.0.0)"]
+
[[package]]
name = "django-ninja"
version = "0.22.2"
@@ -1104,6 +1184,23 @@ files = [
{file = "numpy-1.26.0.tar.gz", hash = "sha256:f93fc78fe8bf15afe2b8d6b6499f1c73953169fad1e9a8dd086cdff3190e7fdf"},
]
+[[package]]
+name = "oauthlib"
+version = "3.2.2"
+description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"},
+ {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"},
+]
+
+[package.extras]
+rsa = ["cryptography (>=3.0.0)"]
+signals = ["blinker (>=1.4.0)"]
+signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
+
[[package]]
name = "packaging"
version = "23.2"
@@ -1454,6 +1551,27 @@ typing-extensions = ">=3.7.4.3"
dotenv = ["python-dotenv (>=0.10.4)"]
email = ["email-validator (>=1.0.3)"]
+[[package]]
+name = "pyjwt"
+version = "2.8.0"
+description = "JSON Web Token implementation in Python"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"},
+ {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"},
+]
+
+[package.dependencies]
+cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""}
+
+[package.extras]
+crypto = ["cryptography (>=3.4.0)"]
+dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
+docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
+tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
+
[[package]]
name = "pyspark"
version = "3.2.0"
@@ -1530,6 +1648,25 @@ files = [
[package.dependencies]
six = ">=1.5"
+[[package]]
+name = "python3-openid"
+version = "3.2.0"
+description = "OpenID support for modern servers and consumers."
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+ {file = "python3-openid-3.2.0.tar.gz", hash = "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf"},
+ {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"},
+]
+
+[package.dependencies]
+defusedxml = "*"
+
+[package.extras]
+mysql = ["mysql-connector-python"]
+postgresql = ["psycopg2"]
+
[[package]]
name = "pytz"
version = "2023.3.post1"
@@ -1732,6 +1869,25 @@ redis = ["redis (>=3)"]
security = ["itsdangerous (>=2.0)"]
yaml = ["pyyaml (>=5.4)"]
+[[package]]
+name = "requests-oauthlib"
+version = "1.3.1"
+description = "OAuthlib authentication support for Requests."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"},
+ {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"},
+]
+
+[package.dependencies]
+oauthlib = ">=3.0.0"
+requests = ">=2.0.0"
+
+[package.extras]
+rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
+
[[package]]
name = "s3transfer"
version = "0.7.0"
@@ -2443,4 +2599,4 @@ indexer = ["ujson", "warcio", "idna", "beautifulsoup4", "lxml", "langdetect", "p
[metadata]
lock-version = "2.0"
python-versions = ">=3.10,<3.11"
-content-hash = "fe5f238c57ec2d09acb6bdf8f46f33c7bbe499f68a7e34ab7bca1336e0ae881c"
+content-hash = "13572a7df206102ce30a6deb1eecd22b5b217a96f864a7dd6c558a7ca263d520"
diff --git a/pyproject.toml b/pyproject.toml
index 4a4a725..a0de7fd 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -37,6 +37,7 @@ django = "^4.2.4"
django-ninja = "^0.22.2"
requests-cache = "^1.1.0"
redis = {extras = ["hiredis"], version = "^5.0.1"}
+django-allauth = "^0.57.0"
[tool.poetry.extras]
indexer = [