From 94ac744d39fdc64ca022c33220ef7b85a0e30c92 Mon Sep 17 00:00:00 2001 From: Pablo Silva Date: Thu, 21 Nov 2024 13:50:23 +0000 Subject: [PATCH 1/7] Fix compile messages path --- etc/scripts/compilemessages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/scripts/compilemessages.py b/etc/scripts/compilemessages.py index 0521787e..1cda8124 100644 --- a/etc/scripts/compilemessages.py +++ b/etc/scripts/compilemessages.py @@ -15,7 +15,7 @@ def main(): """ # Walk entire tree, looking for locale directories basedirs = ["locale"] - for dirpath, dirnames, filenames in os.walk(".", topdown=True): + for dirpath, dirnames, filenames in os.walk("/jandig/locale", topdown=True): for dirname in dirnames: if dirname == "locale": basedirs.append(os.path.join(dirpath, dirname)) From baa67bf6d39d8ba1e154ad8e247bc8d0dc32e895 Mon Sep 17 00:00:00 2001 From: Pablo Silva Date: Thu, 21 Nov 2024 13:53:46 +0000 Subject: [PATCH 2/7] Add validation for invalid string as page number --- src/core/urls.py | 3 ++- src/core/views/views.py | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/core/urls.py b/src/core/urls.py index 72f94734..10353b61 100644 --- a/src/core/urls.py +++ b/src/core/urls.py @@ -6,6 +6,7 @@ from core.views.exhibits import ExhibitViewset from core.views.markers import MarkerViewset from core.views.objects import ObjectViewset +from django.urls import re_path from core.views.static_views import ( community, documentation, @@ -47,7 +48,7 @@ path("manifest.json", manifest, name="manifest"), path("upload", upload_image, name="upload-image"), path("i18n/", include("django.conf.urls.i18n")), - path("see_all/", see_all, name="see_all"), + re_path(r"^see_all(?:/(?P[a-zA-Z]+))?(?:/(?P\d+))?/$", see_all, name="see_all"), path("robots.txt", robots_txt), path("favicon.ico", favicon), path(settings.HEALTH_CHECK_URL, health_check), diff --git a/src/core/views/views.py b/src/core/views/views.py index 5a8a745c..54c0f2e0 100644 --- a/src/core/views/views.py +++ b/src/core/views/views.py @@ -51,12 +51,21 @@ def collection(request): @cache_page(60 * 2) @require_http_methods(["GET"]) -def see_all(request): - request_type = request.GET.get("which") +def see_all(request, which="", page=1): + request_type = request.GET.get("which", which) + if request_type not in ["objects", "markers", "artworks", "exhibits"]: + # Invalid request type, return to collection + return redirect("collection") ctx = {} - per_page = 20 + per_page = 3 page = request.GET.get("page", 1) + try: + # Bots insert random strings in the page parameter + page = int(page) + except ValueError: + page = 1 + data_types = { "objects": Object.objects.all().order_by("uploaded_at"), "markers": Marker.objects.all().order_by("uploaded_at"), @@ -67,10 +76,12 @@ def see_all(request): data = data_types.get(request_type) if data: paginator = Paginator(data, per_page) - data = paginator.get_page(page) - data.adjusted_elided_pages = paginator.get_elided_page_range(page) + if page > paginator.num_pages: + return redirect("see_all", request_type,paginator.num_pages) + paginated_data = paginator.get_page(page) + paginated_data.adjusted_elided_pages = paginator.get_elided_page_range(page) ctx = { - request_type: data, + request_type: paginated_data, "seeall": True, } From 2bd9741d28206de6015797f92958af89066b05c1 Mon Sep 17 00:00:00 2001 From: Pablo Silva Date: Thu, 21 Nov 2024 16:54:25 +0000 Subject: [PATCH 3/7] Create new reset-password view --- .envs/.example | 2 + src/config/settings.py | 14 ++-- .../jinja2/users/html/password_reset.jinja2 | 59 +++++++++++++++ .../users/html/password_reset_complete.jinja2 | 15 ++++ .../users/html/password_reset_confirm.jinja2 | 71 +++++++++++++++++++ .../users/html/password_reset_email.html | 11 +++ .../users/html/password_reset_subject.txt | 1 + src/users/jinja2/users/login.jinja2 | 2 +- src/users/urls.py | 34 +++++---- src/users/views.py | 21 ++++-- 10 files changed, 205 insertions(+), 25 deletions(-) create mode 100644 src/users/jinja2/users/html/password_reset.jinja2 create mode 100644 src/users/jinja2/users/html/password_reset_complete.jinja2 create mode 100644 src/users/jinja2/users/html/password_reset_confirm.jinja2 create mode 100644 src/users/jinja2/users/html/password_reset_email.html create mode 100644 src/users/jinja2/users/html/password_reset_subject.txt diff --git a/.envs/.example b/.envs/.example index 98e5726d..01605030 100644 --- a/.envs/.example +++ b/.envs/.example @@ -37,6 +37,8 @@ POSTGRES_PASSWORD=secret # Email server variables SMTP_SERVER=mailpit SMTP_PORT=1025 +SMTP_USE_TLS=False +SMTP_USE_SSL=False SMTP_USER= SMTP_PASSWORD= SMTP_SENDER_MAIL="jandig@memelab.com.br" diff --git a/src/config/settings.py b/src/config/settings.py index dc8c79b7..8ec6666d 100644 --- a/src/config/settings.py +++ b/src/config/settings.py @@ -194,11 +194,15 @@ def debug(request): # Sphinx docs DOCS_ROOT = "/jandig/build/" -SMTP_SERVER = env("SMTP_SERVER", default="mailpit") -SMTP_PORT = env("SMTP_PORT", default=1025) -SMTP_USER = env("SMTP_USER", default="jandig@jandig.com") -SMTP_PASSWORD = env("SMTP_PASSWORD", default="password") -SMTP_SENDER_MAIL = env("SMTP_SENDER_MAIL", default="jandig@memelab.com.br") + +DEFAULT_FROM_EMAIL = env("SMTP_SENDER_MAIL", default="jandig@memelab.com.br") +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = env("SMTP_SERVER", default="mailpit") +EMAIL_USE_TLS = env("SMTP_USE_TLS", default=False) +EMAIL_PORT = env("SMTP_PORT", default=1025) +EMAIL_HOST_USER = env("SMTP_USER", default="jandig@jandig.com") +EMAIL_HOST_PASSWORD = env("SMTP_PASSWORD", default="password") +EMAIL_USE_SSL = False # Recaptcha RECAPTCHA_ENABLED = env("RECAPTCHA_ENABLED", default=False) diff --git a/src/users/jinja2/users/html/password_reset.jinja2 b/src/users/jinja2/users/html/password_reset.jinja2 new file mode 100644 index 00000000..18146e6a --- /dev/null +++ b/src/users/jinja2/users/html/password_reset.jinja2 @@ -0,0 +1,59 @@ +{% extends '/core/arviewer.jinja2' %} +{% block content %} +
+
+
+
+
+
+
+

Forgot Password?

+
+ {% if form.errors %} + + {% endif %} +
+
+ {{ csrf_input }} +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+{% endblock content %} \ No newline at end of file diff --git a/src/users/jinja2/users/html/password_reset_complete.jinja2 b/src/users/jinja2/users/html/password_reset_complete.jinja2 new file mode 100644 index 00000000..d878ed47 --- /dev/null +++ b/src/users/jinja2/users/html/password_reset_complete.jinja2 @@ -0,0 +1,15 @@ +{% extends '/core/arviewer.jinja2' %} +{% block title %} Password Reset {% endblock title%} +{% block content %} +
+
+
+
+
+ Your password has been set. You may go ahead and Login Here +
+
+
+
+
+{% endblock content %} \ No newline at end of file diff --git a/src/users/jinja2/users/html/password_reset_confirm.jinja2 b/src/users/jinja2/users/html/password_reset_confirm.jinja2 new file mode 100644 index 00000000..ccdef32d --- /dev/null +++ b/src/users/jinja2/users/html/password_reset_confirm.jinja2 @@ -0,0 +1,71 @@ +{% extends '/core/arviewer.jinja2' %} +{% block title %} Password Reset {% endblock title%} +{% block content %} +
+
+
+
+ {% if validlink %} +
+
+

Reset Your Password

+
+ {% if form.errors %} + + {% endif %} + +
+
+ {{ csrf_input }} +
+
+
+ + + + +
+
+
+
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+
+ {% else %} +
+ The password reset link was invalid, possibly because it has already been used. + Please request a new password reset. +
+ {% endif %} +
+
+
+
+{% endblock content %} \ No newline at end of file diff --git a/src/users/jinja2/users/html/password_reset_email.html b/src/users/jinja2/users/html/password_reset_email.html new file mode 100644 index 00000000..e261c607 --- /dev/null +++ b/src/users/jinja2/users/html/password_reset_email.html @@ -0,0 +1,11 @@ + + To initiate the password reset process for your {{ user.email }} Django Registration/Login App Account, + click the link below: + + {{ protocol }}://{{ domain }}{{ url('password_reset_confirm',args=[uid,token]) }} + + If clicking the link above doesn't work, please copy and paste the URL in a new browser + window instead. + + Sincerely, + Jandig Team diff --git a/src/users/jinja2/users/html/password_reset_subject.txt b/src/users/jinja2/users/html/password_reset_subject.txt new file mode 100644 index 00000000..5cb9df8e --- /dev/null +++ b/src/users/jinja2/users/html/password_reset_subject.txt @@ -0,0 +1 @@ +Jandig Password Reset \ No newline at end of file diff --git a/src/users/jinja2/users/login.jinja2 b/src/users/jinja2/users/login.jinja2 index 2b720ba0..451a8114 100644 --- a/src/users/jinja2/users/login.jinja2 +++ b/src/users/jinja2/users/login.jinja2 @@ -46,7 +46,7 @@ diff --git a/src/users/urls.py b/src/users/urls.py index a4fcb038..99804ef9 100644 --- a/src/users/urls.py +++ b/src/users/urls.py @@ -27,6 +27,7 @@ related_content, signup, wrong_verification_code, + ResetPasswordView, ) urlpatterns = [ @@ -40,22 +41,29 @@ name="login", ), path("logout/", auth_views.LogoutView.as_view(), name="logout"), - path("recover/", recover_password, name="recover"), - path("recover-code/", recover_code, name="recover-code"), + path('reset-password/', ResetPasswordView.as_view(), name='reset-password'), + path('password-reset-confirm///', + auth_views.PasswordResetConfirmView.as_view(template_name='users/html/password_reset_confirm.jinja2'), + name='password_reset_confirm'), + path('password-reset-complete/', + auth_views.PasswordResetCompleteView.as_view(template_name='users/html/password_reset_complete.jinja2'), + name='password_reset_complete'), + # path("recover/", recover_password, name="recover"), + # path("recover-code/", recover_code, name="recover-code"), + # path( + # "wrong-verification-code", + # wrong_verification_code, + # name="wrong-verification-code", + # ), + # path( + # "invalid-recovering-email", + # invalid_recovering_email_or_username, + # name="invalid_recovering_email_or_username", + # ), + # path("recover-edit-password", recover_edit_password, name="recover-edit-password"), path("profile/", profile, name="profile"), path("profile/edit/", edit_profile, name="edit-profile"), path("profile/edit-password/", edit_password, name="edit-password"), - path( - "wrong-verification-code", - wrong_verification_code, - name="wrong-verification-code", - ), - path( - "invalid-recovering-email", - invalid_recovering_email_or_username, - name="invalid_recovering_email_or_username", - ), - path("recover-edit-password", recover_edit_password, name="recover-edit-password"), path("markers/upload/", marker_upload, name="marker-upload"), path("objects/upload/", object_upload, name="object-upload"), path("element/get/", element_get, name="element-get"), diff --git a/src/users/views.py b/src/users/views.py index fb60ecf7..80658a18 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -29,13 +29,15 @@ UploadObjectForm, ) from .models import Profile -from .services.email_service import EmailService -from .services.encrypt_service import EncryptService -from .services.recaptcha_service import BOT_SCORE, create_assessment -from .services.user_service import UserService +from .services import ( EmailService,EncryptService ,BOT_SCORE, create_assessment, UserService) +from django.urls import reverse_lazy +from django.contrib.auth.views import PasswordResetView +from django.contrib.messages.views import SuccessMessageMixin log = logging.getLogger(__file__) +User = get_user_model() + def signup(request): if request.method == "POST": @@ -72,8 +74,15 @@ def signup(request): ) -User = get_user_model() - +class ResetPasswordView(SuccessMessageMixin, PasswordResetView): + template_name = 'users/html/password_reset.jinja2' + email_template_name = 'users/html/password_reset_email.html' + subject_template_name = 'users/html/password_reset_subject.txt' + success_message = _("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.") + success_url = reverse_lazy('home') def recover_password(request): if request.method == "POST": From cbbcd3e65a40aebb112a409368fbcbf581d07353 Mon Sep 17 00:00:00 2001 From: Pablo Silva Date: Thu, 21 Nov 2024 16:58:01 +0000 Subject: [PATCH 4/7] Remove old password reset files --- src/users/forms.py | 8 -- .../users/invalid-recovering-email.jinja2 | 22 ---- .../jinja2/users/recover-edit-password.jinja2 | 31 ----- .../jinja2/users/recover-password-code.jinja2 | 31 ----- .../jinja2/users/recover-password.jinja2 | 46 -------- .../users/wrong-verification-code.jinja2 | 22 ---- src/users/services/__init__.py | 1 + src/users/services/email_service.py | 35 ------ src/users/services/encrypt_service.py | 24 ---- src/users/services/user_service.py | 23 ---- src/users/views.py | 107 +----------------- 11 files changed, 4 insertions(+), 346 deletions(-) delete mode 100644 src/users/jinja2/users/invalid-recovering-email.jinja2 delete mode 100644 src/users/jinja2/users/recover-edit-password.jinja2 delete mode 100644 src/users/jinja2/users/recover-password-code.jinja2 delete mode 100644 src/users/jinja2/users/recover-password.jinja2 delete mode 100644 src/users/jinja2/users/wrong-verification-code.jinja2 delete mode 100644 src/users/services/email_service.py delete mode 100644 src/users/services/encrypt_service.py delete mode 100644 src/users/services/user_service.py diff --git a/src/users/forms.py b/src/users/forms.py index 172bfee1..7fb3b6ec 100644 --- a/src/users/forms.py +++ b/src/users/forms.py @@ -171,14 +171,6 @@ def clean(self): return cleaned_data -class RecoverPasswordForm(forms.Form): - username_or_email = forms.CharField(label="username / email", max_length="50") - - -class RecoverPasswordCodeForm(forms.Form): - verification_code = forms.CharField(label="Verification code", max_length="200") - - class UploadMarkerForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(UploadMarkerForm, self).__init__(*args, **kwargs) diff --git a/src/users/jinja2/users/invalid-recovering-email.jinja2 b/src/users/jinja2/users/invalid-recovering-email.jinja2 deleted file mode 100644 index c83aeafa..00000000 --- a/src/users/jinja2/users/invalid-recovering-email.jinja2 +++ /dev/null @@ -1,22 +0,0 @@ -{% extends '/core/arviewer.jinja2' %} - -{% block content %} - -
- - - -
-{% endblock %} \ No newline at end of file diff --git a/src/users/jinja2/users/recover-edit-password.jinja2 b/src/users/jinja2/users/recover-edit-password.jinja2 deleted file mode 100644 index 1d0068a9..00000000 --- a/src/users/jinja2/users/recover-edit-password.jinja2 +++ /dev/null @@ -1,31 +0,0 @@ -{% extends '/core/arviewer.jinja2' %} - -{% block content %} - -
- - - -
-{% endblock %} \ No newline at end of file diff --git a/src/users/jinja2/users/recover-password-code.jinja2 b/src/users/jinja2/users/recover-password-code.jinja2 deleted file mode 100644 index 79fa95ad..00000000 --- a/src/users/jinja2/users/recover-password-code.jinja2 +++ /dev/null @@ -1,31 +0,0 @@ -{% extends '/core/arviewer.jinja2' %} - -{% block content %} - -
- - - -
-{% endblock %} \ No newline at end of file diff --git a/src/users/jinja2/users/recover-password.jinja2 b/src/users/jinja2/users/recover-password.jinja2 deleted file mode 100644 index 1d8efac2..00000000 --- a/src/users/jinja2/users/recover-password.jinja2 +++ /dev/null @@ -1,46 +0,0 @@ -{% extends '/core/arviewer.jinja2' %} - -{% block extra_css%} - -{% endblock %} - -{% block extra_js%} - - {% if recaptcha_enabled %} - - - {% endif %} -{% endblock %} - -{% block content %} -
- - -
-{% endblock %} \ No newline at end of file diff --git a/src/users/jinja2/users/wrong-verification-code.jinja2 b/src/users/jinja2/users/wrong-verification-code.jinja2 deleted file mode 100644 index b3a8ddaf..00000000 --- a/src/users/jinja2/users/wrong-verification-code.jinja2 +++ /dev/null @@ -1,22 +0,0 @@ -{% extends '/core/arviewer.jinja2' %} - -{% block content %} - -
- - - -
-{% endblock %} \ No newline at end of file diff --git a/src/users/services/__init__.py b/src/users/services/__init__.py index e69de29b..f79e22ec 100644 --- a/src/users/services/__init__.py +++ b/src/users/services/__init__.py @@ -0,0 +1 @@ +from .recaptcha_service import * \ No newline at end of file diff --git a/src/users/services/email_service.py b/src/users/services/email_service.py deleted file mode 100644 index fd23ec18..00000000 --- a/src/users/services/email_service.py +++ /dev/null @@ -1,35 +0,0 @@ -import smtplib -from email.mime.multipart import MIMEMultipart -from email.mime.text import MIMEText - -from django.conf import settings - - -class EmailService: - def __init__(self, email_message): - self.smtp_server = settings.SMTP_SERVER - self.smtp_port = settings.SMTP_PORT - self.smtp_user = settings.SMTP_USER - self.smtp_password = settings.SMTP_PASSWORD - self.jandig_email = settings.SMTP_SENDER_MAIL - self.email_message = email_message - - def send_email_to_recover_password(self, multipart_message): - email_server = smtplib.SMTP(self.smtp_server, self.smtp_port) - email_server.starttls() - email_server.login(self.smtp_user, self.smtp_password) - email_server.sendmail( - multipart_message["From"], - multipart_message["To"], - multipart_message.as_string(), - ) - email_server.quit() - - def build_multipart_message(self, user_email): - multipart_message = MIMEMultipart("alternative") - multipart_message["From"] = f"Jandig <{self.jandig_email}>" - multipart_message["To"] = "{}".format(user_email) - multipart_message["Subject"] = "Recover Password" - - multipart_message.attach(MIMEText(self.email_message, "plain")) - return multipart_message diff --git a/src/users/services/encrypt_service.py b/src/users/services/encrypt_service.py deleted file mode 100644 index 6a8e0d1d..00000000 --- a/src/users/services/encrypt_service.py +++ /dev/null @@ -1,24 +0,0 @@ -import hashlib -import secrets -from datetime import datetime - - -class EncryptService: - def generate_verification_code(self, email): - datetime_now = datetime.now() - _year = datetime_now.year - _month = datetime_now.month - _day = datetime_now.day - _hour = datetime_now.hour - _minute = datetime_now.minute - _second = datetime_now.second - _microsec = datetime_now.microsecond - - today = f"{_year}{_month}{_day}{_hour}{_minute}{_second}{_microsec}" - decrypt_code = str(today) + (email * 4) + secrets.token_hex(16) - verification_code = self.generate_hash_code(decrypt_code) - return verification_code - - def generate_hash_code(self, decrypt_code): - hash_code = hashlib.sha256(bytes(decrypt_code, encoding="utf-8")) - return hash_code.hexdigest() diff --git a/src/users/services/user_service.py b/src/users/services/user_service.py deleted file mode 100644 index b79df83e..00000000 --- a/src/users/services/user_service.py +++ /dev/null @@ -1,23 +0,0 @@ -import logging - -from django.contrib.auth.models import User - -log = logging.getLogger("ej") - - -class UserService: - def get_user_email(self, username_or_email): - if "@" in username_or_email: - return username_or_email - user = User.objects.get(username=username_or_email) - log.warning(user) - return user.email - - def check_if_username_or_email_exist(self, username_or_email): - if "@" in username_or_email: - if not User.objects.filter(email=username_or_email).exists(): - return False - else: - if not User.objects.filter(username=username_or_email).exists(): - return False - return True diff --git a/src/users/views.py b/src/users/views.py index 80658a18..8ffba392 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -8,6 +8,8 @@ login, update_session_auth_hash, ) + +from django.utils.translation import gettext_lazy as _ from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import SetPasswordForm from django.http import Http404, JsonResponse @@ -22,14 +24,12 @@ ExhibitForm, PasswordChangeForm, ProfileForm, - RecoverPasswordCodeForm, - RecoverPasswordForm, SignupForm, UploadMarkerForm, UploadObjectForm, ) from .models import Profile -from .services import ( EmailService,EncryptService ,BOT_SCORE, create_assessment, UserService) +from .services import (BOT_SCORE, create_assessment) from django.urls import reverse_lazy from django.contrib.auth.views import PasswordResetView from django.contrib.messages.views import SuccessMessageMixin @@ -84,107 +84,6 @@ class ResetPasswordView(SuccessMessageMixin, PasswordResetView): "please make sure you've entered the address you registered with, and check your spam folder.") success_url = reverse_lazy('home') -def recover_password(request): - if request.method == "POST": - if settings.RECAPTCHA_ENABLED: - recaptcha_token = request.POST.get("g-recaptcha-response") - assessment = create_assessment( - token=recaptcha_token, recaptcha_action="recover_password" - ) - score = assessment.get("riskAnalysis", {}).get("score", -1) - if score <= BOT_SCORE: - return redirect("home") - - recover_password_form = RecoverPasswordForm(request.POST) - - if recover_password_form.is_valid(): - username_or_email = recover_password_form.cleaned_data.get( - "username_or_email" - ) - user_service = UserService() - username_or_email_is_valid = user_service.check_if_username_or_email_exist( - username_or_email - ) - if not username_or_email_is_valid: - return redirect("invalid_recovering_email_or_username") - - global global_recovering_email - global_recovering_email = user_service.get_user_email(username_or_email) - - global global_verification_code - encrypt_service = EncryptService() - global_verification_code = encrypt_service.generate_verification_code( - global_recovering_email - ) - - build_message_and_send_to_user(global_recovering_email) - - return redirect("recover-code") - - recover_password_form = RecoverPasswordForm() - return render( - request, - "users/recover-password.jinja2", - { - "form": recover_password_form, - "recaptcha_enabled": settings.RECAPTCHA_ENABLED, - "recaptcha_site_key": settings.RECAPTCHA_SITE_KEY, - }, - ) - - -def build_message_and_send_to_user(email): - message = f"You have requested a new password. This is your verification code: {global_verification_code}\nCopy it and put into the field." - email_service = EmailService(message) - multipart_message = email_service.build_multipart_message(email) - email_service.send_email_to_recover_password(multipart_message) - - -def recover_code(request): - if request.method == "POST": - form = RecoverPasswordCodeForm(request.POST) - - if form.is_valid(): - code = form.cleaned_data.get("verification_code") - - log.warning("Inserido: %s", code) - log.warning("Correto: %s", global_verification_code) - - if code == global_verification_code: - global recover_password_user - recover_password_user = User.objects.get(email=global_recovering_email) - return redirect("recover-edit-password") - - return redirect("wrong-verification-code") - return redirect("home") - - form = RecoverPasswordCodeForm() - return render(request, "users/recover-password-code.jinja2", {"form": form}) - - -def recover_edit_password(request): - if request.method == "POST": - form = SetPasswordForm(recover_password_user, data=request.POST) - - if form.is_valid(): - form.save() - - return redirect("login") - else: - form = SetPasswordForm(recover_password_user) - - return render(request, "users/recover-edit-password.jinja2", {"form": form}) - - -@require_http_methods(["GET"]) -def wrong_verification_code(request): - return render(request, "users/wrong-verification-code.jinja2") - - -@require_http_methods(["GET"]) -def invalid_recovering_email_or_username(request): - return render(request, "users/invalid-recovering-email.jinja2") - @login_required @require_http_methods(["GET"]) From 879cf07009c65a8adf37b690665c88d51a195121 Mon Sep 17 00:00:00 2001 From: Pablo Silva Date: Thu, 21 Nov 2024 16:58:53 +0000 Subject: [PATCH 5/7] Rename reset-password template folder --- .../users/{html => reset-password}/password_reset.jinja2 | 0 .../{html => reset-password}/password_reset_complete.jinja2 | 0 .../{html => reset-password}/password_reset_confirm.jinja2 | 0 .../{html => reset-password}/password_reset_email.html | 0 .../{html => reset-password}/password_reset_subject.txt | 0 src/users/urls.py | 4 ++-- src/users/views.py | 6 +++--- 7 files changed, 5 insertions(+), 5 deletions(-) rename src/users/jinja2/users/{html => reset-password}/password_reset.jinja2 (100%) rename src/users/jinja2/users/{html => reset-password}/password_reset_complete.jinja2 (100%) rename src/users/jinja2/users/{html => reset-password}/password_reset_confirm.jinja2 (100%) rename src/users/jinja2/users/{html => reset-password}/password_reset_email.html (100%) rename src/users/jinja2/users/{html => reset-password}/password_reset_subject.txt (100%) diff --git a/src/users/jinja2/users/html/password_reset.jinja2 b/src/users/jinja2/users/reset-password/password_reset.jinja2 similarity index 100% rename from src/users/jinja2/users/html/password_reset.jinja2 rename to src/users/jinja2/users/reset-password/password_reset.jinja2 diff --git a/src/users/jinja2/users/html/password_reset_complete.jinja2 b/src/users/jinja2/users/reset-password/password_reset_complete.jinja2 similarity index 100% rename from src/users/jinja2/users/html/password_reset_complete.jinja2 rename to src/users/jinja2/users/reset-password/password_reset_complete.jinja2 diff --git a/src/users/jinja2/users/html/password_reset_confirm.jinja2 b/src/users/jinja2/users/reset-password/password_reset_confirm.jinja2 similarity index 100% rename from src/users/jinja2/users/html/password_reset_confirm.jinja2 rename to src/users/jinja2/users/reset-password/password_reset_confirm.jinja2 diff --git a/src/users/jinja2/users/html/password_reset_email.html b/src/users/jinja2/users/reset-password/password_reset_email.html similarity index 100% rename from src/users/jinja2/users/html/password_reset_email.html rename to src/users/jinja2/users/reset-password/password_reset_email.html diff --git a/src/users/jinja2/users/html/password_reset_subject.txt b/src/users/jinja2/users/reset-password/password_reset_subject.txt similarity index 100% rename from src/users/jinja2/users/html/password_reset_subject.txt rename to src/users/jinja2/users/reset-password/password_reset_subject.txt diff --git a/src/users/urls.py b/src/users/urls.py index 99804ef9..b5ae643b 100644 --- a/src/users/urls.py +++ b/src/users/urls.py @@ -43,10 +43,10 @@ path("logout/", auth_views.LogoutView.as_view(), name="logout"), path('reset-password/', ResetPasswordView.as_view(), name='reset-password'), path('password-reset-confirm///', - auth_views.PasswordResetConfirmView.as_view(template_name='users/html/password_reset_confirm.jinja2'), + auth_views.PasswordResetConfirmView.as_view(template_name='users/reset-password/password_reset_confirm.jinja2'), name='password_reset_confirm'), path('password-reset-complete/', - auth_views.PasswordResetCompleteView.as_view(template_name='users/html/password_reset_complete.jinja2'), + auth_views.PasswordResetCompleteView.as_view(template_name='users/reset-password/password_reset_complete.jinja2'), name='password_reset_complete'), # path("recover/", recover_password, name="recover"), # path("recover-code/", recover_code, name="recover-code"), diff --git a/src/users/views.py b/src/users/views.py index 8ffba392..fae3ee20 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -75,9 +75,9 @@ def signup(request): class ResetPasswordView(SuccessMessageMixin, PasswordResetView): - template_name = 'users/html/password_reset.jinja2' - email_template_name = 'users/html/password_reset_email.html' - subject_template_name = 'users/html/password_reset_subject.txt' + template_name = 'users/reset-password/password_reset.jinja2' + email_template_name = 'users/reset-password/password_reset_email.html' + subject_template_name = 'users/reset-password/password_reset_subject.txt' success_message = _("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, " \ From 48c7c892fb2ff0800ed10351bd845295e01dc583 Mon Sep 17 00:00:00 2001 From: Pablo Silva Date: Thu, 21 Nov 2024 17:05:27 +0000 Subject: [PATCH 6/7] Fix black, isort and flake8 --- src/config/settings.py | 6 ++--- src/core/urls.py | 9 +++++--- src/core/views/views.py | 2 +- src/users/services/__init__.py | 2 +- src/users/urls.py | 42 +++++++++++++--------------------- src/users/views.py | 30 ++++++++++++------------ 6 files changed, 42 insertions(+), 49 deletions(-) diff --git a/src/config/settings.py b/src/config/settings.py index 8ec6666d..c8f5dc3e 100644 --- a/src/config/settings.py +++ b/src/config/settings.py @@ -9,7 +9,7 @@ from django.utils.translation import gettext_lazy as _ from sentry_sdk.integrations.django import DjangoIntegration -from .storage_settings import * # noqa F403 F401 +from .storage_settings import * # noqa F403 F401 ROOT_DIR = environ.Path("/jandig/") BASE_DIR = "/jandig/src" @@ -196,10 +196,10 @@ def debug(request): DEFAULT_FROM_EMAIL = env("SMTP_SENDER_MAIL", default="jandig@memelab.com.br") -EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" EMAIL_HOST = env("SMTP_SERVER", default="mailpit") EMAIL_USE_TLS = env("SMTP_USE_TLS", default=False) -EMAIL_PORT = env("SMTP_PORT", default=1025) +EMAIL_PORT = env("SMTP_PORT", default=1025) EMAIL_HOST_USER = env("SMTP_USER", default="jandig@jandig.com") EMAIL_HOST_PASSWORD = env("SMTP_PASSWORD", default="password") EMAIL_USE_SSL = False diff --git a/src/core/urls.py b/src/core/urls.py index 10353b61..766a916e 100644 --- a/src/core/urls.py +++ b/src/core/urls.py @@ -1,12 +1,11 @@ from django.conf import settings -from django.urls import include, path +from django.urls import include, path, re_path from rest_framework_nested.routers import DefaultRouter from core.views.artworks import ArtworkViewset from core.views.exhibits import ExhibitViewset from core.views.markers import MarkerViewset from core.views.objects import ObjectViewset -from django.urls import re_path from core.views.static_views import ( community, documentation, @@ -48,7 +47,11 @@ path("manifest.json", manifest, name="manifest"), path("upload", upload_image, name="upload-image"), path("i18n/", include("django.conf.urls.i18n")), - re_path(r"^see_all(?:/(?P[a-zA-Z]+))?(?:/(?P\d+))?/$", see_all, name="see_all"), + re_path( + r"^see_all(?:/(?P[a-zA-Z]+))?(?:/(?P\d+))?/$", + see_all, + name="see_all", + ), path("robots.txt", robots_txt), path("favicon.ico", favicon), path(settings.HEALTH_CHECK_URL, health_check), diff --git a/src/core/views/views.py b/src/core/views/views.py index 54c0f2e0..22e33593 100644 --- a/src/core/views/views.py +++ b/src/core/views/views.py @@ -77,7 +77,7 @@ def see_all(request, which="", page=1): if data: paginator = Paginator(data, per_page) if page > paginator.num_pages: - return redirect("see_all", request_type,paginator.num_pages) + return redirect("see_all", request_type, paginator.num_pages) paginated_data = paginator.get_page(page) paginated_data.adjusted_elided_pages = paginator.get_elided_page_range(page) ctx = { diff --git a/src/users/services/__init__.py b/src/users/services/__init__.py index f79e22ec..744f9d1c 100644 --- a/src/users/services/__init__.py +++ b/src/users/services/__init__.py @@ -1 +1 @@ -from .recaptcha_service import * \ No newline at end of file +from .recaptcha_service import * # noqa diff --git a/src/users/urls.py b/src/users/urls.py index b5ae643b..4315f6bc 100644 --- a/src/users/urls.py +++ b/src/users/urls.py @@ -3,6 +3,7 @@ from .forms import LoginForm from .views import ( + ResetPasswordView, create_artwork, create_exhibit, delete, @@ -14,20 +15,14 @@ edit_password, edit_profile, element_get, - invalid_recovering_email_or_username, marker_upload, mod, mod_delete, object_upload, permission_denied, profile, - recover_code, - recover_edit_password, - recover_password, related_content, signup, - wrong_verification_code, - ResetPasswordView, ) urlpatterns = [ @@ -41,26 +36,21 @@ name="login", ), path("logout/", auth_views.LogoutView.as_view(), name="logout"), - path('reset-password/', ResetPasswordView.as_view(), name='reset-password'), - path('password-reset-confirm///', - auth_views.PasswordResetConfirmView.as_view(template_name='users/reset-password/password_reset_confirm.jinja2'), - name='password_reset_confirm'), - path('password-reset-complete/', - auth_views.PasswordResetCompleteView.as_view(template_name='users/reset-password/password_reset_complete.jinja2'), - name='password_reset_complete'), - # path("recover/", recover_password, name="recover"), - # path("recover-code/", recover_code, name="recover-code"), - # path( - # "wrong-verification-code", - # wrong_verification_code, - # name="wrong-verification-code", - # ), - # path( - # "invalid-recovering-email", - # invalid_recovering_email_or_username, - # name="invalid_recovering_email_or_username", - # ), - # path("recover-edit-password", recover_edit_password, name="recover-edit-password"), + path("reset-password/", ResetPasswordView.as_view(), name="reset-password"), + path( + "password-reset-confirm///", + auth_views.PasswordResetConfirmView.as_view( + template_name="users/reset-password/password_reset_confirm.jinja2" + ), + name="password_reset_confirm", + ), + path( + "password-reset-complete/", + auth_views.PasswordResetCompleteView.as_view( + template_name="users/reset-password/password_reset_complete.jinja2" + ), + name="password_reset_complete", + ), path("profile/", profile, name="profile"), path("profile/edit/", edit_profile, name="edit-profile"), path("profile/edit-password/", edit_password, name="edit-password"), diff --git a/src/users/views.py b/src/users/views.py index fae3ee20..3b7609fb 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -8,12 +8,13 @@ login, update_session_auth_hash, ) - -from django.utils.translation import gettext_lazy as _ from django.contrib.auth.decorators import login_required -from django.contrib.auth.forms import SetPasswordForm +from django.contrib.auth.views import PasswordResetView +from django.contrib.messages.views import SuccessMessageMixin from django.http import Http404, JsonResponse from django.shortcuts import get_object_or_404, redirect, render +from django.urls import reverse_lazy +from django.utils.translation import gettext_lazy as _ from django.views.decorators.cache import cache_page from django.views.decorators.http import require_http_methods @@ -29,10 +30,7 @@ UploadObjectForm, ) from .models import Profile -from .services import (BOT_SCORE, create_assessment) -from django.urls import reverse_lazy -from django.contrib.auth.views import PasswordResetView -from django.contrib.messages.views import SuccessMessageMixin +from .services import BOT_SCORE, create_assessment log = logging.getLogger(__file__) @@ -75,14 +73,16 @@ def signup(request): class ResetPasswordView(SuccessMessageMixin, PasswordResetView): - template_name = 'users/reset-password/password_reset.jinja2' - email_template_name = 'users/reset-password/password_reset_email.html' - subject_template_name = 'users/reset-password/password_reset_subject.txt' - success_message = _("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.") - success_url = reverse_lazy('home') + template_name = "users/reset-password/password_reset.jinja2" + email_template_name = "users/reset-password/password_reset_email.html" + subject_template_name = "users/reset-password/password_reset_subject.txt" + success_message = _( + "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." + ) + success_url = reverse_lazy("home") @login_required From d98742726146d61e1c9c03c89dc39bf2cc6f59cd Mon Sep 17 00:00:00 2001 From: Pablo Silva Date: Thu, 21 Nov 2024 17:11:06 +0000 Subject: [PATCH 7/7] Update reset password e-mail text --- src/users/jinja2/users/reset-password/password_reset_email.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/users/jinja2/users/reset-password/password_reset_email.html b/src/users/jinja2/users/reset-password/password_reset_email.html index e261c607..e00e10f0 100644 --- a/src/users/jinja2/users/reset-password/password_reset_email.html +++ b/src/users/jinja2/users/reset-password/password_reset_email.html @@ -1,5 +1,5 @@ - To initiate the password reset process for your {{ user.email }} Django Registration/Login App Account, + To initiate the password reset process for your {{ user.email }} Jandig account, click the link below: {{ protocol }}://{{ domain }}{{ url('password_reset_confirm',args=[uid,token]) }}