From c5bfd77b349696e213bad6ae776f2602cf85e8d0 Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Mon, 31 Oct 2022 17:08:23 +0100 Subject: [PATCH] Implement registration --- envs/docker-local-envs.env | 6 ++ envs/local-envs.env | 6 ++ envs/test-envs.env | 6 ++ poetry.lock | 58 ++++++++++++++++++- pyproject.toml | 2 + src/charasheet/settings.py | 16 ++++- src/charasheet/urls.py | 9 +++ src/common/forms.py | 8 +++ .../activation_complete.html | 7 +++ .../activation_email_body.txt | 2 + .../activation_email_subject.txt | 1 + .../activation_failed.html | 8 +++ .../registration_closed.html | 6 ++ .../registration_complete.html | 6 ++ .../registration_form.html | 10 ++++ src/common/templates/registration/login.html | 13 +++++ 16 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 src/common/forms.py create mode 100644 src/common/templates/django_registration/activation_complete.html create mode 100644 src/common/templates/django_registration/activation_email_body.txt create mode 100644 src/common/templates/django_registration/activation_email_subject.txt create mode 100644 src/common/templates/django_registration/activation_failed.html create mode 100644 src/common/templates/django_registration/registration_closed.html create mode 100644 src/common/templates/django_registration/registration_complete.html create mode 100644 src/common/templates/django_registration/registration_form.html create mode 100644 src/common/templates/registration/login.html diff --git a/envs/docker-local-envs.env b/envs/docker-local-envs.env index 0fab4ff..4a2f2b9 100644 --- a/envs/docker-local-envs.env +++ b/envs/docker-local-envs.env @@ -15,3 +15,9 @@ LOG_LEVEL=DEBUG # SQLITE DB ############################################################################### DATABASE_URL=sqlite:////app/db/db.sqlite3 + +############################################################################### +# EMAIL +############################################################################### +#MAILGUN_API_KEY= +MAILGUN_SENDER_DOMAIN=mg.augendre.info diff --git a/envs/local-envs.env b/envs/local-envs.env index ad36665..5f2cf3f 100644 --- a/envs/local-envs.env +++ b/envs/local-envs.env @@ -10,3 +10,9 @@ ALLOWED_HOSTS=localhost,127.0.0.1 # LOGGING ############################################################################### LOG_LEVEL=DEBUG + +############################################################################### +# EMAIL +############################################################################### +#MAILGUN_API_KEY= +MAILGUN_SENDER_DOMAIN=mg.augendre.info diff --git a/envs/test-envs.env b/envs/test-envs.env index ea55ff9..666a1b9 100644 --- a/envs/test-envs.env +++ b/envs/test-envs.env @@ -10,3 +10,9 @@ ALLOWED_HOSTS=localhost,127.0.0.1 # LOGGING ############################################################################### LOG_LEVEL=DEBUG + +############################################################################### +# EMAIL +############################################################################### +#MAILGUN_API_KEY= +MAILGUN_SENDER_DOMAIN=mg.augendre.info diff --git a/poetry.lock b/poetry.lock index 3ae1d58..cf2f377 100644 --- a/poetry.lock +++ b/poetry.lock @@ -120,7 +120,7 @@ python-versions = ">=3.6.1" name = "charset-normalizer" version = "2.1.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "dev" +category = "main" optional = false python-versions = ">=3.6.0" @@ -135,6 +135,17 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +[[package]] +name = "confusable-homoglyphs" +version = "3.2.0" +description = "Detect confusable usage of unicode homoglyphs, prevent homograph attacks." +category = "main" +optional = false +python-versions = "*" + +[package.extras] +cli = ["click"] + [[package]] name = "coverage" version = "6.5.0" @@ -194,6 +205,23 @@ tzdata = {version = "*", markers = "sys_platform == \"win32\""} argon2 = ["argon2-cffi (>=19.1.0)"] bcrypt = ["bcrypt"] +[[package]] +name = "django-anymail" +version = "8.6" +description = "Django email backends and webhooks for Amazon SES, Mailgun, Mailjet, Mandrill, Postal, Postmark, SendGrid, SendinBlue, and SparkPost" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +django = ">=2.0" +requests = ">=2.4.3" + +[package.extras] +amazon_ses = ["boto3"] +dev = ["flake8", "sphinx", "sphinx-rtd-theme", "tox", "twine", "wheel"] +postal = ["cryptography"] + [[package]] name = "django-browser-reload" version = "1.6.0" @@ -271,6 +299,18 @@ python-versions = ">=3.7" [package.dependencies] Django = ">=3.2" +[[package]] +name = "django-registration" +version = "3.3" +description = "An extensible user-registration application for Django" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +confusable-homoglyphs = ">=3.0,<4.0" +Django = ">=3.2" + [[package]] name = "exceptiongroup" version = "1.0.0" @@ -708,7 +748,7 @@ python-versions = ">=3.6" name = "requests" version = "2.28.1" description = "Python HTTP for Humans." -category = "dev" +category = "main" optional = false python-versions = ">=3.7, <4" @@ -916,7 +956,7 @@ h11 = ">=0.9.0,<1" [metadata] lock-version = "1.1" python-versions = ">=3.10.0, <4" -content-hash = "df8aa35ecf2515691ed8ffdccbfb63f503c9330db3cd806d7dc8a8689f64328e" +content-hash = "2005841e057ea97d65b1582d1454765504d5146e98ffe5e2023e694ef093f6a4" [metadata.files] ansicon = [ @@ -1029,6 +1069,10 @@ colorama = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +confusable-homoglyphs = [ + {file = "confusable_homoglyphs-3.2.0-py2.py3-none-any.whl", hash = "sha256:e3ce611028d882b74a5faa69e3cbb5bd4dcd9f69936da6e73d33eda42c917944"}, + {file = "confusable_homoglyphs-3.2.0.tar.gz", hash = "sha256:3b4a0d9fa510669498820c91a0bfc0c327568cecec90648cf3819d4a6fc6a751"}, +] coverage = [ {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, @@ -1130,6 +1174,10 @@ django = [ {file = "Django-4.1.2-py3-none-any.whl", hash = "sha256:26dc24f99c8956374a054bcbf58aab8dc0cad2e6ac82b0fe036b752c00eee793"}, {file = "Django-4.1.2.tar.gz", hash = "sha256:b8d843714810ab88d59344507d4447be8b2cf12a49031363b6eed9f1b9b2280f"}, ] +django-anymail = [ + {file = "django-anymail-8.6.tar.gz", hash = "sha256:783342d49dd07d68778b81dd12a94c86e1d217463a68a85450a0513fabe31345"}, + {file = "django_anymail-8.6-py3-none-any.whl", hash = "sha256:49d83d7c16316ca86a624097496881d59b7d71b16bf1c5211cffa5b19ef98d0c"}, +] django-browser-reload = [ {file = "django-browser-reload-1.6.0.tar.gz", hash = "sha256:9ca69c71796f53868bdc7421f120d147f7a64faa0d5d8c06970ba3f8061af63c"}, {file = "django_browser_reload-1.6.0-py3-none-any.whl", hash = "sha256:31b8b2d51e8faa5878f21e6b60b8f43e1123907c6e082e9e967962ba63958829"}, @@ -1158,6 +1206,10 @@ django-linear-migrations = [ {file = "django-linear-migrations-2.5.1.tar.gz", hash = "sha256:4dbba1a42ce10dc40df295f7fa2fd28d6f7b31035353f7f1a752d07c71391073"}, {file = "django_linear_migrations-2.5.1-py3-none-any.whl", hash = "sha256:9b6c4157c0ee21b78affc3c9a76e89d9df7ad9239a4378d48dc7247a914f6c72"}, ] +django-registration = [ + {file = "django-registration-3.3.tar.gz", hash = "sha256:884a4cc9ec87b9f1c0ceb6b6c4b7ba491c1877997a3cd29cc923697dac785eb8"}, + {file = "django_registration-3.3-py3-none-any.whl", hash = "sha256:dfa176f594fb465c93495caa55686be723a15829769511383e25172d2efbd0e6"}, +] exceptiongroup = [ {file = "exceptiongroup-1.0.0-py3-none-any.whl", hash = "sha256:2ac84b496be68464a2da60da518af3785fff8b7ec0d090a581604bc870bdee41"}, {file = "exceptiongroup-1.0.0.tar.gz", hash = "sha256:affbabf13fb6e98988c38d9c5650e701569fe3c1de3233cfb61c5f33774690ad"}, diff --git a/pyproject.toml b/pyproject.toml index 4d9bfb6..a1ec93a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,8 @@ whitenoise = ">=6.2" uWSGI = ">=2.0.21" selenium = ">=4.5.0" Markdown = ">=3.2" +django-registration = ">=3.3" +django-anymail = {extras = ["mailgun"], version = ">=8.6"} [tool.poetry.dev-dependencies] django-debug-toolbar = ">=3.2" diff --git a/src/charasheet/settings.py b/src/charasheet/settings.py index 967c2f5..5242c13 100644 --- a/src/charasheet/settings.py +++ b/src/charasheet/settings.py @@ -18,6 +18,9 @@ env = environ.Env( LOG_FORMAT=(str, "default"), APP_DATA=(Path, PROJECT_ROOT / "data"), DATABASE_URL=(str, "sqlite:////app/db/db.sqlite3"), + REGISTRATION_OPEN=(bool, True), + MAILGUN_API_KEY=(str, ""), + MAILGUN_SENDER_DOMAIN=(str, ""), ) env_file = os.getenv("ENV_FILE", None) @@ -200,7 +203,18 @@ AUTHENTICATION_BACKENDS = ("django.contrib.auth.backends.ModelBackend",) LOGOUT_REDIRECT_URL = "/" LOGIN_REDIRECT_URL = "/" -LOGIN_URL = "/admin/login" +LOGIN_URL = "login" DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" AUTH_USER_MODEL = "common.User" + +ACCOUNT_ACTIVATION_DAYS = 2 +REGISTRATION_OPEN = env("REGISTRATION_OPEN") + +ANYMAIL = { + "MAILGUN_API_KEY": env("MAILGUN_API_KEY"), + "MAILGUN_SENDER_DOMAIN": env("MAILGUN_SENDER_DOMAIN"), +} +EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend" +DEFAULT_FROM_EMAIL = "charasheet@mg.augendre.info" +SERVER_EMAIL = "charasheet@mg.augendre.info" diff --git a/src/charasheet/urls.py b/src/charasheet/urls.py index ed14bba..799685d 100644 --- a/src/charasheet/urls.py +++ b/src/charasheet/urls.py @@ -18,11 +18,20 @@ from django.conf.urls.static import static from django.contrib import admin from django.contrib.auth import logout from django.urls import include, path +from django_registration.backends.activation.views import RegistrationView +from common.forms import RegistrationForm from common.views import hello_world urlpatterns = [ path("logout/", logout, {"next_page": settings.LOGOUT_REDIRECT_URL}, name="logout"), + path( + "accounts/register/", + RegistrationView.as_view(form_class=RegistrationForm), + name="django_registration_register", + ), + path("accounts/", include("django_registration.backends.activation.urls")), + path("accounts/", include("django.contrib.auth.urls")), path("admin/", admin.site.urls), path("", hello_world, name="hello_world"), path("character/", include("character.urls", namespace="character")), diff --git a/src/common/forms.py b/src/common/forms.py new file mode 100644 index 0000000..b63633f --- /dev/null +++ b/src/common/forms.py @@ -0,0 +1,8 @@ +import django_registration.forms + +from common.models import User + + +class RegistrationForm(django_registration.forms.RegistrationForm): + class Meta(django_registration.forms.RegistrationForm.Meta): + model = User diff --git a/src/common/templates/django_registration/activation_complete.html b/src/common/templates/django_registration/activation_complete.html new file mode 100644 index 0000000..8f609b1 --- /dev/null +++ b/src/common/templates/django_registration/activation_complete.html @@ -0,0 +1,7 @@ +{% extends "common/base.html" %} + +{% block content %} +

Activation réussie

+

Votre compte est désormais actif.

+

Se connecter

+{% endblock %} diff --git a/src/common/templates/django_registration/activation_email_body.txt b/src/common/templates/django_registration/activation_email_body.txt new file mode 100644 index 0000000..e76e294 --- /dev/null +++ b/src/common/templates/django_registration/activation_email_body.txt @@ -0,0 +1,2 @@ +Voici votre clé d'activation : https://{{ site.domain }}{% url "django_registration_activate" activation_key=activation_key %} +Elle est valable pendant {{ expiration_days }} jours. diff --git a/src/common/templates/django_registration/activation_email_subject.txt b/src/common/templates/django_registration/activation_email_subject.txt new file mode 100644 index 0000000..005a96c --- /dev/null +++ b/src/common/templates/django_registration/activation_email_subject.txt @@ -0,0 +1 @@ +[Character Sheet] Activation de compte diff --git a/src/common/templates/django_registration/activation_failed.html b/src/common/templates/django_registration/activation_failed.html new file mode 100644 index 0000000..8cdb98b --- /dev/null +++ b/src/common/templates/django_registration/activation_failed.html @@ -0,0 +1,8 @@ +{% extends "common/base.html" %} + +{% block content %} +

Erreur d'activation

+

+ {{ activation_error }} +

+{% endblock %} diff --git a/src/common/templates/django_registration/registration_closed.html b/src/common/templates/django_registration/registration_closed.html new file mode 100644 index 0000000..7a92514 --- /dev/null +++ b/src/common/templates/django_registration/registration_closed.html @@ -0,0 +1,6 @@ +{% extends "common/base.html" %} + +{% block content %} +

Inscriptions fermées

+

Les inscriptions sont désactivées.

+{% endblock %} diff --git a/src/common/templates/django_registration/registration_complete.html b/src/common/templates/django_registration/registration_complete.html new file mode 100644 index 0000000..19209d9 --- /dev/null +++ b/src/common/templates/django_registration/registration_complete.html @@ -0,0 +1,6 @@ +{% extends "common/base.html" %} + +{% block content %} +

Inscription réussie

+

Un e-mail permettant d'activer votre compte vous a été envoyé.

+{% endblock %} diff --git a/src/common/templates/django_registration/registration_form.html b/src/common/templates/django_registration/registration_form.html new file mode 100644 index 0000000..b79105e --- /dev/null +++ b/src/common/templates/django_registration/registration_form.html @@ -0,0 +1,10 @@ +{% extends "common/base.html" %} + +{% block content %} +

Inscription

+
+ {{ form.as_p }} + {% csrf_token %} + +
+{% endblock %} diff --git a/src/common/templates/registration/login.html b/src/common/templates/registration/login.html new file mode 100644 index 0000000..18271a5 --- /dev/null +++ b/src/common/templates/registration/login.html @@ -0,0 +1,13 @@ +{% extends "common/base.html" %} + +{% block content %} +

Connexion

+
+ {{ form.as_p }} + {% csrf_token %} + + + Create account + +
+{% endblock %}