diff options
author | Matthew Lemon <y@yulqen.org> | 2024-12-09 17:16:41 +0000 |
---|---|---|
committer | Matthew Lemon <y@yulqen.org> | 2024-12-09 17:16:41 +0000 |
commit | b481069d9444cc0756bd9f6780e7700dcf4903f5 (patch) | |
tree | 5cba9e3d501f79747c8af22bd1b0fd7d783e7ded | |
parent | d3dda8c0bd194c28cf11c189c150c00bdc3e8a83 (diff) |
wip: moving home page to home app and implementing reCAPTCHA
-rw-r--r-- | alphabetlearning/pages/__init__.py | 0 | ||||
-rw-r--r-- | alphabetlearning/pages/admin.py | 3 | ||||
-rw-r--r-- | alphabetlearning/pages/apps.py | 6 | ||||
-rw-r--r-- | alphabetlearning/pages/migrations/__init__.py | 0 | ||||
-rw-r--r-- | alphabetlearning/pages/models.py | 3 | ||||
-rw-r--r-- | alphabetlearning/pages/tests.py | 3 | ||||
-rw-r--r-- | alphabetlearning/pages/urls.py | 8 | ||||
-rw-r--r-- | alphabetlearning/pages/views.py | 5 | ||||
-rw-r--r-- | alphabetlearning/payments/forms.py | 5 | ||||
-rw-r--r-- | alphabetlearning/payments/views.py | 2 | ||||
-rw-r--r-- | alphabetlearning/templates/base.html | 2 | ||||
-rw-r--r-- | alphabetlearning/templates/pages/home.html | 3 | ||||
-rw-r--r-- | alphabetlearning/templates/payments/rate_limited.html | 11 | ||||
-rw-r--r-- | config/settings/base.py | 5 | ||||
-rw-r--r-- | config/settings/production.py | 1 | ||||
-rw-r--r-- | config/urls.py | 5 | ||||
-rw-r--r-- | cookies.txt | 5 | ||||
-rw-r--r-- | pyproject.toml | 3 | ||||
-rw-r--r-- | uv.lock | 14 |
19 files changed, 80 insertions, 4 deletions
diff --git a/alphabetlearning/pages/__init__.py b/alphabetlearning/pages/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/alphabetlearning/pages/__init__.py diff --git a/alphabetlearning/pages/admin.py b/alphabetlearning/pages/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/alphabetlearning/pages/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/alphabetlearning/pages/apps.py b/alphabetlearning/pages/apps.py new file mode 100644 index 0000000..cdd024b --- /dev/null +++ b/alphabetlearning/pages/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class PagesConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'pages' diff --git a/alphabetlearning/pages/migrations/__init__.py b/alphabetlearning/pages/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/alphabetlearning/pages/migrations/__init__.py diff --git a/alphabetlearning/pages/models.py b/alphabetlearning/pages/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/alphabetlearning/pages/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/alphabetlearning/pages/tests.py b/alphabetlearning/pages/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/alphabetlearning/pages/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/alphabetlearning/pages/urls.py b/alphabetlearning/pages/urls.py new file mode 100644 index 0000000..f8c5b15 --- /dev/null +++ b/alphabetlearning/pages/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from . import views + +app_name = "pages" +urlpatterns = [ + path("", views.HomePageView.as_view(), name="home"), +] diff --git a/alphabetlearning/pages/views.py b/alphabetlearning/pages/views.py new file mode 100644 index 0000000..81d4392 --- /dev/null +++ b/alphabetlearning/pages/views.py @@ -0,0 +1,5 @@ +from django.views.generic import TemplateView + + +class HomePageView(TemplateView): + template_name = "pages/home.html" diff --git a/alphabetlearning/payments/forms.py b/alphabetlearning/payments/forms.py index 3aa2d95..68acfee 100644 --- a/alphabetlearning/payments/forms.py +++ b/alphabetlearning/payments/forms.py @@ -1,8 +1,13 @@ from django import forms +from django_recaptcha.fields import ReCaptchaField +from django_recaptcha.widgets import ReCaptchaV2Checkbox + from .models import EmailVerification class EmailVerificationForm(forms.ModelForm): + captcha = ReCaptchaField(widget=ReCaptchaV2Checkbox) + class Meta: model = EmailVerification fields = ["email"] diff --git a/alphabetlearning/payments/views.py b/alphabetlearning/payments/views.py index 2be5344..7682c35 100644 --- a/alphabetlearning/payments/views.py +++ b/alphabetlearning/payments/views.py @@ -61,6 +61,8 @@ class SuccessEmailSignupView(TemplateView): @ratelimit(key="ip", rate="2/m", block=True) def email_signup_verification(request): if request.method == "POST": + if getattr(request, "limited", False): + return render(request, "payments/rate_limited.html", status=429) form = EmailVerificationForm(request.POST) if form.is_valid(): # Create pending verification diff --git a/alphabetlearning/templates/base.html b/alphabetlearning/templates/base.html index 5aa2193..f26fb72 100644 --- a/alphabetlearning/templates/base.html +++ b/alphabetlearning/templates/base.html @@ -59,7 +59,7 @@ <header> <nav class="navbar navbar-expand-lg navbar-light bg-white"> <div class="container-fluid"> - <a class="navbar-brand" href="{% url "home" %}"> + <a class="navbar-brand" href="{% url "pages:home" %}"> <img style="margin-left: 2rem; margin-top: 20px;" src="{% static "images/AL_long_logo_black_grey.png" %}" width=300px alt="Alphabet Learning Logo"> </a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" diff --git a/alphabetlearning/templates/pages/home.html b/alphabetlearning/templates/pages/home.html index 6261524..0d00042 100644 --- a/alphabetlearning/templates/pages/home.html +++ b/alphabetlearning/templates/pages/home.html @@ -65,6 +65,9 @@ placeholder="Your email address..." /> </div> + <div> + {{ form.captcha }} + </div> <button type="submit" style=" diff --git a/alphabetlearning/templates/payments/rate_limited.html b/alphabetlearning/templates/payments/rate_limited.html new file mode 100644 index 0000000..c75e474 --- /dev/null +++ b/alphabetlearning/templates/payments/rate_limited.html @@ -0,0 +1,11 @@ +{% extends "base.html" %} + +{% load static %} + +{% block content %} + <div class="container my-5"> + <div class="row"> + <h2>You have made to many submissions</h2> + <p>Please try again later.</p> + </div> +{% endblock content %} diff --git a/config/settings/base.py b/config/settings/base.py index 157926b..991605c 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -77,6 +77,7 @@ THIRD_PARTY_APPS = [ "allauth.mfa", "allauth.socialaccount", "django_celery_beat", + "django_recaptcha", ] STRIPE_SECRET_KEY = env("STRIPE_SECRET_KEY") @@ -88,6 +89,7 @@ LOCAL_APPS = [ "alphabetlearning.users", "alphabetlearning.resources", "alphabetlearning.payments", + "alphabetlearning.pages", # Your stuff: custom apps go here ] # https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps @@ -366,3 +368,6 @@ CACHES = { "LOCATION": "rate_limit_cache", }, } + +RECAPTCHA_PUBLIC_KEY = env("RECAPTCHA_PUBLIC_KEY") +RECAPTCHA_PRIVATE_KEY = env("RECAPTCHA_PRIVATE_KEY") diff --git a/config/settings/production.py b/config/settings/production.py index 374be33..ff9e475 100644 --- a/config/settings/production.py +++ b/config/settings/production.py @@ -233,3 +233,4 @@ MAILGUN_API_URL = env("MAILGUN_API_URL", default="https://api.eu.mailgun.net/v3" USE_X_FORWARDED_HOST = True SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") +RECAPTCHA_USE_SSL = True # Use HTTPS for requests diff --git a/config/urls.py b/config/urls.py index e213522..554d227 100644 --- a/config/urls.py +++ b/config/urls.py @@ -12,10 +12,11 @@ from django.views.generic import TemplateView # import debug_toolbar -admin.site.site_header = "Blackbird Admin Panel" +admin.site.site_header = "Alphabet Learning Admin Panel" urlpatterns = [ - path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), + # path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), + path("", include("alphabetlearning.pages.urls", namespace="pages")), path( "about/", TemplateView.as_view(template_name="pages/about.html"), diff --git a/cookies.txt b/cookies.txt new file mode 100644 index 0000000..6bef457 --- /dev/null +++ b/cookies.txt @@ -0,0 +1,5 @@ +# Netscape HTTP Cookie File +# https://curl.se/docs/http-cookies.html +# This file was generated by libcurl! Edit at your own risk. + +#HttpOnly_127.0.0.1 FALSE / FALSE 1765141225 csrftoken ZvMDpDcXBf12tnCdJGlR0i8AcBUnh0rX diff --git a/pyproject.toml b/pyproject.toml index b2d4262..d09d98b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,8 @@ dependencies = [ # https://github.com/samuelcolvin/watchfiles "stripe==11.1.0", "django-stubs[compatible-mypy]>=5.0.4", - "django-ratelimit==4.1.0" + "django-ratelimit==4.1.0", + "django-recaptcha==4.0.0" ] [tool.uv] # https://docs.astral.sh/uv/concepts/dependencies/#development-dependencies dev-dependencies = [ @@ -18,6 +18,7 @@ dependencies = [ { name = "django-environ" }, { name = "django-model-utils" }, { name = "django-ratelimit" }, + { name = "django-recaptcha" }, { name = "django-redis" }, { name = "django-storages" }, { name = "django-stubs", extra = ["compatible-mypy"] }, @@ -66,6 +67,7 @@ requires-dist = [ { name = "django-environ", specifier = "==0.11.2" }, { name = "django-model-utils", specifier = "==4.5.1" }, { name = "django-ratelimit", specifier = "==4.1.0" }, + { name = "django-recaptcha", specifier = "==4.0.0" }, { name = "django-redis", specifier = "==5.4.0" }, { name = "django-storages", specifier = "==1.14.3" }, { name = "django-stubs", extras = ["compatible-mypy"], specifier = ">=5.0.4" }, @@ -540,6 +542,18 @@ wheels = [ ] [[package]] +name = "django-recaptcha" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "django" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d4/6b/6edf89da076b2d1ea042e14f116de80be18d25b17af158038d5fc14c00bb/django-recaptcha-4.0.0.tar.gz", hash = "sha256:5316438f97700c431d65351470d1255047e3f2cd9af0f2f13592b637dad9213e", size = 22907 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/d7/09cefb2b4a7dc9ed8a6aabb176ea86eb904a8f73671358436e4b0aa81b93/django_recaptcha-4.0.0-py3-none-any.whl", hash = "sha256:0d912d5c7c009df4e47accd25029133d47a74342dbd2a8edc2877b6bffa971a3", size = 21915 }, +] + +[[package]] name = "django-redis" version = "5.4.0" source = { registry = "https://pypi.org/simple" } |