From 0d4eb81bf2d8a60cec301edc32d7c5f3971aa091 Mon Sep 17 00:00:00 2001 From: dcz2 <dcz@ipipan.waw.pl> Date: Fri, 8 Apr 2022 22:14:41 +0200 Subject: [PATCH] Setting, resetting password, e-mail conf, standarize quotes --- .environment-dev | 15 ++- locale/en/LC_MESSAGES/django.mo | Bin 34225 -> 35733 bytes locale/en/LC_MESSAGES/django.po | 100 +++++++++++++++--- locale/en/LC_MESSAGES/djangojs.po | 2 +- shellvalier/settings.py | 10 +- users/forms.py | 37 +++++-- .../commands/create_groups_and_permissions.py | 14 +-- users/templates/{registration => }/login.html | 6 +- users/templates/new_user_email.html | 11 ++ users/templates/password_change.html | 19 ++++ .../{registration => }/password_reset.html | 6 +- users/templates/password_reset_email.html | 11 ++ users/templates/password_reset_form.html | 23 ++++ users/templates/password_reset_requested.html | 17 +++ users/templates/user_form.html | 2 +- users/templates/user_list.html | 14 +-- users/templates/user_profile.html | 2 +- users/urls.py | 54 +++++++--- users/utils.py | 14 +++ users/views.py | 5 +- 20 files changed, 298 insertions(+), 64 deletions(-) rename users/templates/{registration => }/login.html (71%) create mode 100644 users/templates/new_user_email.html create mode 100644 users/templates/password_change.html rename users/templates/{registration => }/password_reset.html (69%) create mode 100644 users/templates/password_reset_email.html create mode 100644 users/templates/password_reset_form.html create mode 100644 users/templates/password_reset_requested.html create mode 100644 users/utils.py diff --git a/.environment-dev b/.environment-dev index 335bee0..d92b941 100644 --- a/.environment-dev +++ b/.environment-dev @@ -1,9 +1,16 @@ -UWSGI_PROCESS_PER_CONTAINER=4 -DEBUG=true ALLOWED_HOSTS=localhost,127.0.0.1 -SECRET_KEY=Ixosoh1iemoh0Heloh1thee5akooboonu5veehae4aikoh2ohg DATABASE_HOST=shellvalier-postgresql DATABASE_NAME=shellvalier -DATABASE_USER=shellvalier DATABASE_PASSWORD=shellvalier DATABASE_PORT=5432 +DATABASE_USER=shellvalier +DEBUG=true +EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend +EMAIL_HOST= +EMAIL_PORT=25 +EMAIL_HOST_USER= +EMAIL_HOST_PASSWORD= +EMAIL_USE_TLS=false +EMAIL_USE_SSL=false +SECRET_KEY=Ixosoh1iemoh0Heloh1thee5akooboonu5veehae4aikoh2ohg +UWSGI_PROCESS_PER_CONTAINER=4 diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo index f7595614722432da63fc8ccf1e3efcd5f783fe8f..29f13eb298a0c8e679ff2df730c09217471e3bb9 100644 GIT binary patch delta 12340 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 delta 10796 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 diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index 56413e0..2986a6f 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-04-07 23:17+0200\n" +"POT-Creation-Date: 2022-04-08 21:59+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -46,9 +46,8 @@ msgstr "Your profile" msgid "Wyloguj się" msgstr "Sign out" -#: common/templates/base.html:89 users/forms.py:71 -#: users/templates/registration/login.html:6 -#: users/templates/registration/login.html:12 +#: common/templates/base.html:89 users/forms.py:74 users/templates/login.html:6 +#: users/templates/login.html:12 msgid "Zaloguj się" msgstr "Sign in" @@ -2290,28 +2289,100 @@ msgstr "distributive phrase" msgid "fraza posesywna" msgstr "possesive phrase" -#: users/forms.py:10 users/templates/user_list.html:21 +#: users/forms.py:12 users/templates/user_list.html:21 msgid "Grupa" msgstr "Group" -#: users/forms.py:29 users/forms.py:59 +#: users/forms.py:31 users/forms.py:61 msgid "Zapisz" msgstr "Save" -#: users/forms.py:30 users/forms.py:60 +#: users/forms.py:32 users/forms.py:63 users/forms.py:84 users/forms.py:93 +#: users/forms.py:102 msgid "Wróć" msgstr "Back" -#: users/forms.py:84 +#: users/forms.py:62 users/templates/password_change.html:6 +#: users/templates/password_change.html:12 +msgid "Zmień swoje hasło" +msgstr "Change your password" + +#: users/forms.py:75 +msgid "Nie pamiętam hasła" +msgstr "I forgot my password" + +#: users/forms.py:83 msgid "Zresetuj hasło" msgstr "Reset password" -#: users/templates/registration/password_reset.html:6 -#: users/templates/registration/password_reset.html:12 +#: users/forms.py:92 +msgid "Zmień hasło" +msgstr "Change password" + +#: users/forms.py:101 +msgid "Ustaw hasło" +msgstr "Set password" + +#: users/templates/new_user_email.html:2 +#, python-format +msgid "Otrzymujesz ten e-mail, ponieważ ktoś zaprosił Cię do %(site_name)s." +msgstr "" +"You're receiving this email because you have been invited to %(site_name)s." + +#: users/templates/new_user_email.html:4 +msgid "Przejdź na poniższą stronę i ustaw swoje hasło:" +msgstr "Please go to the following page and set your password:" + +#: users/templates/new_user_email.html:8 +msgid "Twoja nazwa użytkownika" +msgstr "Your username" + +#: users/templates/new_user_email.html:10 +#: users/templates/password_reset_email.html:10 +#, python-format +msgid "Zespół %(site_name)s" +msgstr "The %(site_name)s team" + +#: users/templates/password_reset.html:6 users/templates/password_reset.html:12 msgid "Zresetuj swoje hasło" msgstr "Reset your password" -#: users/templates/user_list.html:12 users/views.py:35 +#: users/templates/password_reset_email.html:2 +#, python-format +msgid "" +"Otrzymujesz ten e-mail w związku z prośbą o zmianę hasła Twojego użytkownia " +"na %(site_name)s." +msgstr "" +"You're receiving this email because you requested a password reset for your " +"user account at %(site_name)s." + +#: users/templates/password_reset_email.html:4 +msgid "Przejdź na poniższą stronę i ustaw swoje nowe hasło:" +msgstr "Please go to the following page and choose a new password:" + +#: users/templates/password_reset_email.html:8 +msgid "Twoja nazwa użytkownia:" +msgstr "Your username, in case you’ve forgotten:" + +#: users/templates/password_reset_form.html:6 +#: users/templates/password_reset_form.html:12 +msgid "Ustaw swoje nowe hasło" +msgstr "Choose your new password" + +#: users/templates/password_reset_requested.html:6 +#: users/templates/password_reset_requested.html:12 +msgid "Sprawdź swoją skrzynkę e-mail" +msgstr "Please check your e-mail inbox" + +#: users/templates/password_reset_requested.html:13 +msgid "" +"Wysłaliśmy na Twój adres e-mail link, po kliknięciu którego uzyskasz " +"możliwość wprowadzenia swojego nowego hasła." +msgstr "" +"We've sent you an e-mail containing a link you can use to set your new " +"password." + +#: users/templates/user_list.html:12 users/views.py:38 msgid "Dodaj użytkownika" msgstr "Add a user" @@ -2335,7 +2406,12 @@ msgstr "Actions" msgid "Edytuj" msgstr "Edit" -#: users/views.py:48 +#: users/utils.py:7 +#, python-format +msgid "Zaproszenie do %s" +msgstr "An invitation to %s" + +#: users/views.py:51 msgid "Edytuj użytkownika" msgstr "Edit user" diff --git a/locale/en/LC_MESSAGES/djangojs.po b/locale/en/LC_MESSAGES/djangojs.po index fb7fa6f..e5f578e 100644 --- a/locale/en/LC_MESSAGES/djangojs.po +++ b/locale/en/LC_MESSAGES/djangojs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-04-07 23:17+0200\n" +"POT-Creation-Date: 2022-04-08 21:59+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/shellvalier/settings.py b/shellvalier/settings.py index 89ee949..4bd5bef 100644 --- a/shellvalier/settings.py +++ b/shellvalier/settings.py @@ -162,6 +162,14 @@ STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'common/static/'), ] -LOGIN_URL = reverse_lazy("users:login") +LOGIN_URL = reverse_lazy('users:login') LOGIN_REDIRECT_URL = reverse_lazy('dash') LOGOUT_REDIRECT_URL = reverse_lazy('dash') + +EMAIL_BACKEND = get_environment('EMAIL_BACKEND') +EMAIL_HOST = get_environment('EMAIL_HOST') +EMAIL_PORT = get_environment('EMAIL_PORT', mapper=int) +EMAIL_HOST_USER = get_environment('EMAIL_HOST_USER') +EMAIL_HOST_PASSWORD = get_environment('EMAIL_HOST_PASSWORD') +EMAIL_USE_TLS = get_environment('EMAIL_USE_TLS', mapper=boolean_mapper) +EMAIL_USE_SSL = get_environment('EMAIL_USE_SSL', mapper=boolean_mapper) diff --git a/users/forms.py b/users/forms.py index e0d98f1..054b6af 100644 --- a/users/forms.py +++ b/users/forms.py @@ -1,13 +1,15 @@ from django import forms from django.contrib.auth.models import Group, User -from django.utils.translation import gettext as _ +from django.urls import reverse_lazy +from django.utils.text import format_lazy +from django.utils.translation import gettext_lazy as _ from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Layout, Fieldset, ButtonHolder, Submit class UserForm(forms.ModelForm): - group = forms.ModelChoiceField(queryset=Group.objects.all(), label=_("Grupa")) + group = forms.ModelChoiceField(queryset=Group.objects.all(), label=_('Grupa')) class Meta: model = User @@ -27,7 +29,7 @@ class UserForm(forms.ModelForm): Fieldset('', 'first_name', 'last_name', 'username', 'email', 'group', 'is_active'), ButtonHolder( Submit('submit', _('Zapisz'), css_class='btn btn-sm btn-success'), - HTML('''<a class="btn btn-sm btn-light" href="{% url 'users:user_list' %}">''' + _('Wróć') + '</a>'), + HTML(format_lazy('<a class="btn btn-sm btn-light" href="{}">{}</a>', reverse_lazy('users:user_list'), _('Wróć'))), ), ) for field in ['first_name', 'last_name', 'email']: @@ -57,7 +59,8 @@ class UserProfileForm(forms.ModelForm): Fieldset('', 'first_name', 'last_name', 'email'), ButtonHolder( Submit('submit', _('Zapisz'), css_class='btn btn-sm btn-success'), - HTML('''<a class="btn btn-sm btn-light" href="{% url 'dash' %}">''' + _('Wróć') + '</a>'), + HTML(format_lazy('<a class="btn btn-sm btn-light" href="{}">{}</a>', reverse_lazy('users:password_change'), _('Zmień swoje hasło'))), + HTML(format_lazy('<a class="btn btn-sm btn-light" href="{}">{}</a>', reverse_lazy('dash'), _('Wróć'))), ), ) for field in ['first_name', 'last_name', 'email']: @@ -69,11 +72,7 @@ login_form_helper.layout = Layout( Fieldset('', 'username', 'password'), ButtonHolder( Submit('submit', _('Zaloguj się'), css_class='btn btn-sm btn-success'), - HTML( - '''<a class="btn btn-sm btn-light" href="{% url 'users:password_reset' %}">''' - f"{_('Nie pamiętam hasła')}" - '</a>' - ), + HTML(format_lazy('<a class="btn btn-sm btn-light" href="{}">{}</a>', reverse_lazy('users:password_reset'), _('Nie pamiętam hasła'))), ), ) @@ -82,6 +81,24 @@ password_reset_form_helper.layout = Layout( Fieldset('', 'email'), ButtonHolder( Submit('submit', _('Zresetuj hasło'), css_class='btn btn-sm btn-success'), - HTML('''<a class="btn btn-sm btn-light" href="{% url 'users:login' %}">''' f"{_('Wróć')}" '</a>'), + HTML(format_lazy('<a class="btn btn-sm btn-light" href="{}">{}</a>', reverse_lazy('users:login'), _('Wróć'))), + ) +) + +password_change_form_helper = FormHelper() +password_change_form_helper.layout = Layout( + Fieldset('', 'old_password', 'new_password1', 'new_password2'), + ButtonHolder( + Submit('submit', _('Zmień hasło'), css_class='btn btn-sm btn-success'), + HTML(format_lazy('<a class="btn btn-sm btn-light" href="{}">{}</a>', reverse_lazy('users:user_profile'), _("Wróć"))), + ) +) + +password_reset_set_password_form_helper = FormHelper() +password_reset_set_password_form_helper.layout = Layout( + Fieldset('', 'new_password1', 'new_password2'), + ButtonHolder( + Submit('submit', _('Ustaw hasło'), css_class='btn btn-sm btn-success'), + HTML(format_lazy('<a class="btn btn-sm btn-light" href="{}">{}</a>', reverse_lazy('dash'), _("Wróć"))), ) ) diff --git a/users/management/commands/create_groups_and_permissions.py b/users/management/commands/create_groups_and_permissions.py index 195d2d1..a4361ca 100644 --- a/users/management/commands/create_groups_and_permissions.py +++ b/users/management/commands/create_groups_and_permissions.py @@ -5,18 +5,18 @@ from django.core.management.base import BaseCommand class Command(BaseCommand): def handle(self, **options): - admins, __ = Group.objects.get_or_create(name="Admini") + admins, __ = Group.objects.get_or_create(name='Admini') admins.permissions.add( - Permission.objects.get(codename="view_user", content_type=ContentType.objects.get_for_model(User)), - Permission.objects.get(codename="add_user", content_type=ContentType.objects.get_for_model(User)), - Permission.objects.get(codename="change_user", content_type=ContentType.objects.get_for_model(User)), - Permission.objects.get(codename="delete_user", content_type=ContentType.objects.get_for_model(User)), + Permission.objects.get(codename='view_user', content_type=ContentType.objects.get_for_model(User)), + Permission.objects.get(codename='add_user', content_type=ContentType.objects.get_for_model(User)), + Permission.objects.get(codename='change_user', content_type=ContentType.objects.get_for_model(User)), + Permission.objects.get(codename='delete_user', content_type=ContentType.objects.get_for_model(User)), ) - lexicographs, __ = Group.objects.get_or_create(name="Leksykografowie") + lexicographs, __ = Group.objects.get_or_create(name='Leksykografowie') lexicographs.permissions.add( # TODO ) - super_lexicographs, __ = Group.objects.get_or_create(name="Super Leksykografowie") + super_lexicographs, __ = Group.objects.get_or_create(name='Super Leksykografowie') super_lexicographs.permissions.add( # TODO ) diff --git a/users/templates/registration/login.html b/users/templates/login.html similarity index 71% rename from users/templates/registration/login.html rename to users/templates/login.html index 10834c7..d184db3 100644 --- a/users/templates/registration/login.html +++ b/users/templates/login.html @@ -1,15 +1,15 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% load i18n %} {% load crispy_forms_filters %} -{% block title %}{% trans "Zaloguj się" %}{% endblock %} +{% block title %}{% trans 'Zaloguj się' %}{% endblock %} {% block content %} <div class="row m-0"> <div class="col-lg-4 col-md-6 m-auto"> <div class="bg-white mt-4 p-3 clearfix"> - <h5 class="mt-2 mb-4">{% trans "Zaloguj się" %}</h5> + <h5 class="mt-2 mb-4">{% trans 'Zaloguj się' %}</h5> <form action="." method="post"> {% crispy form helper %} </form> diff --git a/users/templates/new_user_email.html b/users/templates/new_user_email.html new file mode 100644 index 0000000..1d4ca57 --- /dev/null +++ b/users/templates/new_user_email.html @@ -0,0 +1,11 @@ +{% load i18n %}{% autoescape off %} +{% blocktranslate %}Otrzymujesz ten e-mail, ponieważ ktoś zaprosił Cię do {{ site_name }}.{% endblocktranslate %} + +{% translate 'Przejdź na poniższą stronę i ustaw swoje hasło:' %} +{% block reset_link %} +{{ protocol }}://{{ domain }}{% url 'users:password_reset' %} +{% endblock %} +{% translate 'Twoja nazwa użytkownika' %}: {{ user.get_username }} + +{% blocktranslate %}Zespół {{ site_name }}{% endblocktranslate %} +{% endautoescape %} diff --git a/users/templates/password_change.html b/users/templates/password_change.html new file mode 100644 index 0000000..33ac0d7 --- /dev/null +++ b/users/templates/password_change.html @@ -0,0 +1,19 @@ +{% extends 'base.html' %} + +{% load i18n %} +{% load crispy_forms_filters %} + +{% block title %}{% trans 'Zmień swoje hasło' %}{% endblock %} + +{% block content %} + <div class="row m-0"> + <div class="col-lg-4 col-md-6 m-auto"> + <div class="bg-white mt-4 p-3 clearfix"> + <h5 class="mt-2 mb-4">{% trans 'Zmień swoje hasło' %}</h5> + <form action="." method="post"> + {% crispy form helper %} + </form> + </div> + </div> + </div> +{% endblock %} diff --git a/users/templates/registration/password_reset.html b/users/templates/password_reset.html similarity index 69% rename from users/templates/registration/password_reset.html rename to users/templates/password_reset.html index 7d37fa9..195135c 100644 --- a/users/templates/registration/password_reset.html +++ b/users/templates/password_reset.html @@ -1,15 +1,15 @@ -{% extends "base.html" %} +{% extends 'base.html' %} {% load i18n %} {% load crispy_forms_filters %} -{% block title %}{% trans "Zresetuj swoje hasło" %}{% endblock %} +{% block title %}{% trans 'Zresetuj swoje hasło' %}{% endblock %} {% block content %} <div class="row m-0"> <div class="col-lg-4 col-md-6 m-auto"> <div class="bg-white mt-4 p-3 clearfix"> - <h5 class="mt-2 mb-4">{% trans "Zresetuj swoje hasło" %}</h5> + <h5 class="mt-2 mb-4">{% trans 'Zresetuj swoje hasło' %}</h5> <form action="." method="post"> {% crispy form helper %} </form> diff --git a/users/templates/password_reset_email.html b/users/templates/password_reset_email.html new file mode 100644 index 0000000..32d2ae9 --- /dev/null +++ b/users/templates/password_reset_email.html @@ -0,0 +1,11 @@ +{% load i18n %}{% autoescape off %} +{% blocktranslate %}Otrzymujesz ten e-mail w związku z prośbą o zmianę hasła Twojego użytkownia na {{ site_name }}.{% endblocktranslate %} + +{% translate 'Przejdź na poniższą stronę i ustaw swoje nowe hasło:' %} +{% block reset_link %} +{{ protocol }}://{{ domain }}{% url 'users:password_reset_confirm' uidb64=uid token=token %} +{% endblock %} +{% translate 'Twoja nazwa użytkownia:' %} {{ user.get_username }} + +{% blocktranslate %}Zespół {{ site_name }}{% endblocktranslate %} +{% endautoescape %} diff --git a/users/templates/password_reset_form.html b/users/templates/password_reset_form.html new file mode 100644 index 0000000..83e179e --- /dev/null +++ b/users/templates/password_reset_form.html @@ -0,0 +1,23 @@ +{% extends 'base.html' %} + +{% load i18n %} +{% load crispy_forms_filters %} + +{% block title %}{% trans 'Ustaw swoje nowe hasło' %}{% endblock %} + +{% block content %} + <div class="row m-0"> + <div class="col-lg-4 col-md-6 m-auto"> + <div class="bg-white mt-4 p-3 clearfix"> + <h5 class="mt-2 mb-4">{% trans 'Ustaw swoje nowe hasło' %}</h5> + <form action="." method="post"> + {% if form %} + {% crispy form helper %} + {% else %} + <div class="alert alert-danger">{{ title }}</div> + {% endif %} + </form> + </div> + </div> + </div> +{% endblock %} diff --git a/users/templates/password_reset_requested.html b/users/templates/password_reset_requested.html new file mode 100644 index 0000000..84a64e3 --- /dev/null +++ b/users/templates/password_reset_requested.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} + +{% load i18n %} +{% load crispy_forms_filters %} + +{% block title %}{% trans 'Sprawdź swoją skrzynkę e-mail' %}{% endblock %} + +{% block content %} + <div class="row m-0"> + <div class="col-lg-4 col-md-6 m-auto"> + <div class="bg-white mt-4 p-3 clearfix"> + <h5 class="mt-2 mb-4">{% trans 'Sprawdź swoją skrzynkę e-mail' %}</h5> + <p>{% trans 'Wysłaliśmy na Twój adres e-mail link, po kliknięciu którego uzyskasz możliwość wprowadzenia swojego nowego hasła.' %}</p> + </div> + </div> + </div> +{% endblock %} diff --git a/users/templates/user_form.html b/users/templates/user_form.html index 82fbbf3..25d2a46 100644 --- a/users/templates/user_form.html +++ b/users/templates/user_form.html @@ -1,4 +1,4 @@ -{% extends "base-margins.html" %} +{% extends 'base-margins.html' %} {% load i18n %} diff --git a/users/templates/user_list.html b/users/templates/user_list.html index c3b0051..4d84c66 100644 --- a/users/templates/user_list.html +++ b/users/templates/user_list.html @@ -1,4 +1,4 @@ -{% extends "base-margins.html" %} +{% extends 'base-margins.html' %} {% load i18n %} @@ -16,11 +16,11 @@ <table class="table"> <thead> <tr> - <th>{% trans "Imię i nazwisko" %}</th> - <th>{% trans "Nazwa użytkownika" %}</th> - <th>{% trans "Grupa" %}</th> - <th>{% trans "Aktywny" %}</th> - <th>{% trans "Akcje" %}</th> + <th>{% trans 'Imię i nazwisko' %}</th> + <th>{% trans 'Nazwa użytkownika' %}</th> + <th>{% trans 'Grupa' %}</th> + <th>{% trans 'Aktywny' %}</th> + <th>{% trans 'Akcje' %}</th> </tr> </thead> <tbody> @@ -28,7 +28,7 @@ <tr> <td>{{ user.get_full_name }}</td> <td>{{ user.username }}</td> - <td>{{ user.groups.all|join:", " }}</td> + <td>{{ user.groups.all|join:', ' }}</td> <td>{{ user.is_active|yesno }}</td> <td><a href="{% url 'users:user_edit' pk=user.pk %}" class="btn btn-xs btn-outline-dark">{% trans 'Edytuj' %}</a></td> </tr> diff --git a/users/templates/user_profile.html b/users/templates/user_profile.html index 35db9c2..e29608c 100644 --- a/users/templates/user_profile.html +++ b/users/templates/user_profile.html @@ -1,4 +1,4 @@ -{% extends "base-margins.html" %} +{% extends 'base-margins.html' %} {% load i18n %} diff --git a/users/urls.py b/users/urls.py index 76ae1fa..03b60f1 100644 --- a/users/urls.py +++ b/users/urls.py @@ -1,29 +1,57 @@ -from django.urls import include, path, reverse_lazy - from django.contrib.auth import views as auth_views +from django.urls import include, path, reverse_lazy +from django.views.generic import TemplateView from . import views -from .forms import login_form_helper, password_reset_form_helper +from . import forms app_name = 'users' urlpatterns = [ - path('', views.user_list, name="user_list"), - path('add/', views.user_add, name="user_add"), - path('<int:pk>/edit/', views.user_edit, name="user_edit"), - path('profile/', views.user_profile, name="user_profile"), + path('', views.user_list, name='user_list'), + path('add/', views.user_add, name='user_add'), + path('<int:pk>/edit/', views.user_edit, name='user_edit'), + path('profile/', views.user_profile, name='user_profile'), path( 'login/', - auth_views.LoginView.as_view(extra_context={"helper": login_form_helper}, success_url=reverse_lazy('dash')), - name="login", + auth_views.LoginView.as_view( + template_name='login.html', + success_url=reverse_lazy('dash'), + extra_context={'helper': forms.login_form_helper}, + ), + name='login', ), - path('logout/', auth_views.LogoutView.as_view(), name="logout"), + path('logout/', auth_views.LogoutView.as_view(), name='logout'), + path( + 'psasword-change/', + auth_views.PasswordChangeView.as_view( + template_name='password_change.html', + success_url=reverse_lazy('users:user_profile'), + extra_context={'helper': forms.password_change_form_helper}, + ), + name='password_change'), path( 'password-reset/', auth_views.PasswordResetView.as_view( - template_name="registration/password_reset.html", - extra_context={"helper": password_reset_form_helper}, + template_name='password_reset.html', + email_template_name='password_reset_email.html', + success_url=reverse_lazy('users:password_reset_requested'), + extra_context={'helper': forms.password_reset_form_helper}, + ), + name='password_reset', + ), + path( + 'password-reset/check-your-inbox/', + TemplateView.as_view(template_name='password_reset_requested.html'), + name='password_reset_requested', + ), + path( + 'password-reset/<uidb64>/<token>/', + auth_views.PasswordResetConfirmView.as_view( + template_name='password_reset_form.html', + success_url=reverse_lazy('users:login'), + extra_context={'helper': forms.password_reset_set_password_form_helper}, ), - name="password_reset", + name='password_reset_confirm' ), ] diff --git a/users/utils.py b/users/utils.py new file mode 100644 index 0000000..ae63178 --- /dev/null +++ b/users/utils.py @@ -0,0 +1,14 @@ +from django.core.mail import send_mail +from django.utils.translation import gettext as _ +from django.template import loader + + +def send_new_user_email(site, user, use_https): + subject = _('Zaproszenie do %s') % (site.name, ) + body = loader.render_to_string('new_user_email.html', { + 'site_name': site.name, + 'protocol': 'https' if use_https else 'http', + 'domain': site.domain, + 'user': user, + }) + send_mail(subject, body, from_email=None, recipient_list=[user.email]) diff --git a/users/views.py b/users/views.py index 97b3b5a..9e9a6a8 100644 --- a/users/views.py +++ b/users/views.py @@ -1,9 +1,11 @@ from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.models import User +from django.contrib.sites.shortcuts import get_current_site from django.shortcuts import get_object_or_404, render, redirect from django.utils.translation import gettext_lazy as _ from users.forms import UserForm, UserProfileForm +from users.utils import send_new_user_email @permission_required('users.view_user') @@ -28,7 +30,8 @@ def user_add(request): if request.method == 'POST': form = UserForm(instance=User(), data=request.POST) if form.is_valid(): - form.save() + user = form.save() + send_new_user_email(site=get_current_site(request), user=user, use_https=request.is_secure()) return redirect('users:user_list') else: form = UserForm(instance=User()) -- GitLab