From 6ffe2083b973275084882d419b220c382e55cd2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=C3=A1=C5=A1=20Havelka?= Date: Sun, 26 Sep 2021 15:48:05 +0200 Subject: [PATCH] =?UTF-8?q?P=C5=99esun=20autentizace=20ze=20semin=C3=A1?= =?UTF-8?q?=C5=99e=20do=20various/autentizace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mamweb/settings_common.py | 1 + mamweb/urls.py | 3 + seminar/forms.py | 10 --- seminar/models.py | 32 --------- seminar/urls.py | 13 +--- seminar/views/views_all.py | 71 ++----------------- various/autentizace/__init__.py | 0 various/autentizace/models.py | 27 +++++++ .../templates/autentizace}/login.html | 0 .../templates/autentizace}/logout.html | 0 .../templates/autentizace}/nove_heslo.html | 0 .../autentizace}/nove_nastaveno.html | 0 .../autentizace}/password_reset_email.html | 0 .../autentizace}/password_reset_subject.txt | 0 .../templates/autentizace}/reset_hesla.html | 0 .../templates/autentizace}/reset_poslan.html | 0 various/autentizace/urls.py | 15 ++++ various/autentizace/utils.py | 31 ++++++++ various/autentizace/views.py | 45 ++++++++++++ 19 files changed, 128 insertions(+), 120 deletions(-) create mode 100644 various/autentizace/__init__.py create mode 100644 various/autentizace/models.py rename {seminar/templates/seminar/profil => various/autentizace/templates/autentizace}/login.html (100%) rename {seminar/templates/seminar/profil => various/autentizace/templates/autentizace}/logout.html (100%) rename {seminar/templates/seminar/registrace => various/autentizace/templates/autentizace}/nove_heslo.html (100%) rename {seminar/templates/seminar/registrace => various/autentizace/templates/autentizace}/nove_nastaveno.html (100%) rename {seminar/templates/seminar/registrace => various/autentizace/templates/autentizace}/password_reset_email.html (100%) rename {seminar/templates/seminar/registrace => various/autentizace/templates/autentizace}/password_reset_subject.txt (100%) rename {seminar/templates/seminar/registrace => various/autentizace/templates/autentizace}/reset_hesla.html (100%) rename {seminar/templates/seminar/registrace => various/autentizace/templates/autentizace}/reset_poslan.html (100%) create mode 100644 various/autentizace/urls.py create mode 100644 various/autentizace/utils.py create mode 100644 various/autentizace/views.py diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index f4e9ac89..8f49375d 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -135,6 +135,7 @@ INSTALLED_APPS = ( 'prednasky', 'header_fotky', 'various', + 'various.autentizace', # Admin upravy: diff --git a/mamweb/urls.py b/mamweb/urls.py index 2f5aeea9..a9acedac 100644 --- a/mamweb/urls.py +++ b/mamweb/urls.py @@ -23,6 +23,9 @@ urlpatterns = [ # Prednaskova aplikace (ma vlastni podadresare) path('', include('prednasky.urls')), + # Autentizační aplikace (ma vlastni podadresare) + path('', include('various.autentizace.urls')), + # Comments (interni i verejne) path('comments_dj/', include('django_comments.urls')), path('comments_fl/', include('fluent_comments.urls')), diff --git a/seminar/forms.py b/seminar/forms.py index cfc013ec..19ed8d9f 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -27,16 +27,6 @@ class TelInput(forms.TextInput): input_type = 'tel' input_pattern="^[+]?[()/0-9. -]{9,}$" -class LoginForm(forms.Form): - username = forms.CharField(label='Přihlašovací jméno', - max_length=256, - required=True) - password = forms.CharField( - label='Heslo', - max_length=256, - required=True, - widget=forms.PasswordInput()) - class PrihlaskaForm(PasswordResetForm): username = forms.CharField(label='Přihlašovací jméno', diff --git a/seminar/models.py b/seminar/models.py index 535544c0..d4c3ad81 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -1778,35 +1778,3 @@ class Novinky(models.Model): return '[' + str(self.datum) + '] ' + self.text[0:50] else: return '[' + str(self.datum) + '] ' - - - - -# FIXME: Tohle nepatří do aplikace 'seminar' -# Nefunkční alternativa vestavěného Usera, který má jméno a mail v přidružené Osobě -# from django.contrib.auth.models import User as Django_User -# -# class Uzivatel(Django_User): -# class Meta: -# proxy = True -# -# @property -# def first_name(self): -# osoby = Osoba.objects.filter(user=self) -# if len(osoby) == 0: -# return None -# return osoby.first().krestni_jmeno -# -# @property -# def last_name(self): -# osoby = Osoba.objects.filter(user=self) -# if len(osoby) == 0: -# return None -# return osoby.first().prijmeni -# -# @property -# def email(self): -# osoby = Osoba.objects.filter(user=self) -# if len(osoby) == 0: -# return None -# return osoby.first().email diff --git a/seminar/urls.py b/seminar/urls.py index 141453c7..eee9511f 100644 --- a/seminar/urls.py +++ b/seminar/urls.py @@ -2,7 +2,6 @@ from django.urls import path, include, re_path from django.contrib.auth.decorators import login_required from . import views, export from .utils import org_required, resitel_required, viewMethodSwitch, resitel_or_org_required -from django.views.generic.base import RedirectView urlpatterns = [ # path('aktualni/temata/', views.TemataRozcestnikView), @@ -133,17 +132,9 @@ urlpatterns = [ ), path('prihlaska/',views.prihlaskaView, name='seminar_prihlaska'), - path('prihlasit/', views.LoginView.as_view(), name='login'), - path('login/', RedirectView.as_view(pattern_name='login', permanent=True, query_string=True)), - path('odhlasit/', views.LogoutView.as_view(), name='logout'), - path('logout/', RedirectView.as_view(pattern_name='logout', permanent=True, query_string=True)), - path('resitel/', resitel_required(views.ResitelView.as_view()), name='seminar_resitel'), + path('resitel/odevzdana_reseni/', resitel_or_org_required(views.PrehledOdevzdanychReseni.as_view()), name='seminar_resitel_odevzdana_reseni'), - path('reset-hesla/', views.PasswordResetView.as_view(), name='reset_password'), - path('zmena-hesla/', views.PasswordChangeView.as_view(), name='change_password'), - path('reset-hesla/2/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), - path('reset-hesla/potvrzeni///', views.PasswordResetConfirmView.as_view(), name='reset_password_confirm'), - path('reset-hesla/hotovo/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'), + path( 'resitel/osobni-udaje/', login_required(views.resitelEditView), diff --git a/seminar/views/views_all.py b/seminar/views/views_all.py index 6b037fcf..56e2aaae 100644 --- a/seminar/views/views_all.py +++ b/seminar/views/views_all.py @@ -1,12 +1,8 @@ -from django.contrib.auth.tokens import PasswordResetTokenGenerator -from django.contrib.sites.shortcuts import get_current_site from django.shortcuts import get_object_or_404, render, redirect from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse from django.urls import reverse,reverse_lazy from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.core.mail import send_mail -from django.utils.encoding import force_bytes -from django.utils.http import urlsafe_base64_encode from django.views import generic from django.utils.translation import ugettext as _ from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect @@ -15,8 +11,6 @@ from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.debug import sensitive_post_parameters from django.views.generic.edit import FormView, CreateView from django.views.generic.base import TemplateView, RedirectView -from django.contrib.auth import authenticate, login, get_user_model, logout -from django.contrib.auth import views as auth_views from django.contrib.auth.models import User, Permission, Group from django.contrib.auth.mixins import LoginRequiredMixin from django.db import transaction @@ -29,7 +23,7 @@ import seminar.models as m from seminar.models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva from seminar import utils, treelib -from seminar.forms import PrihlaskaForm, LoginForm, ProfileEditForm, PoMaturiteProfileEditForm +from seminar.forms import PrihlaskaForm, ProfileEditForm, PoMaturiteProfileEditForm import seminar.forms as f import seminar.templatetags.treenodes as tnltt import seminar.views.views_rest as vr @@ -54,6 +48,8 @@ import logging import time from seminar.utils import aktivniResitele, resi_v_rocniku, problemy_rocniku, cisla_rocniku, hlavni_problemy_f +from various.autentizace.views import LoginView +from various.autentizace.utils import posli_reset_hesla # ze starého modelu #def verejna_temata(rocnik): @@ -1336,30 +1332,7 @@ def prihlaskaView(request): if diffattrs: err_logger.warning(f'Different fields when matching Řešitel id {r.id} or Osoba id {o.id}: {diffattrs}') - uid = urlsafe_base64_encode(force_bytes(u.pk)) - token = PasswordResetTokenGenerator().make_token(u) - url = "https://%s%s" % ( - str(get_current_site(request)), - str(reverse_lazy("reset_password_confirm", args=[uid, token])) - ) - - u.email_user( - subject="Vítej mezi řešiteli M&M!", - message="""Milý řešiteli, milá řešitelko, - -tvůj e-mail byl právě zaregistrován na mam.matfyz.cz. Heslo si prosím nastav na: %s - -Těšíme se na tvé příspěvky do našeho semináře, -Organizátoři M&M - --- - -Tento e-mail byl vygenerován automaticky, chceš-li nás kontaktovat, napiš nám na adresu mam@matfyz.cz. -""" % url, - # TODO: templates/seminar/registrace a django/contrib/auth/forms.py říkají, jak na to lépe - from_email="registrace@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? - ) - + posli_reset_hesla(u, request) return formularOKView(request, text='Na tvůj e-mail jsme právě poslali odkaz pro nastavení hesla.') # if a GET (or any other method) we'll create a blank form @@ -1368,42 +1341,6 @@ Tento e-mail byl vygenerován automaticky, chceš-li nás kontaktovat, napiš n return render(request, 'seminar/profil/prihlaska.html', {'form': form}) -# FIXME: Tohle asi vlastně vůbec nepatří do aplikace 'seminar' -class LoginView(auth_views.LoginView): - # Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL - template_name = 'seminar/profil/login.html' - -class LogoutView(auth_views.LogoutView): - # Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL - template_name = 'seminar/profil/logout.html' - # Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité. - next_page = reverse_lazy('titulni_strana') - -# Nejsem si jistý, který view co dostává, tak zahazuji všechny POSTy -class PasswordResetView(auth_views.PasswordResetView): - """ Chci resetovat heslo. """ - template_name = 'seminar/registrace/reset_hesla.html' - success_url = reverse_lazy('reset_password_done') - from_email = 'login@mam.mff.cuni.cz' - email_template_name = 'seminar/registrace/password_reset_email.html' - subject_template_name = 'seminar/registrace/password_reset_subject.txt' - -class PasswordResetDoneView(auth_views.PasswordResetDoneView): - """ Poslali jsme e-mail (pokud bylo kam)). """ - template_name = 'seminar/registrace/reset_poslan.html' - -class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): - """ Vymysli si heslo. """ - template_name = 'seminar/registrace/nove_heslo.html' - success_url = reverse_lazy('reset_password_complete') - -class PasswordResetCompleteView(auth_views.PasswordResetCompleteView): - """ Heslo se asi změnilo.""" - template_name = 'seminar/registrace/nove_nastaveno.html' - -class PasswordChangeView(auth_views.PasswordChangeView): - #template_name = 'seminar/password_change.html' - success_url = reverse_lazy('titulni_strana') class VueTestView(generic.TemplateView): template_name = 'seminar/vuetest.html' diff --git a/various/autentizace/__init__.py b/various/autentizace/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/various/autentizace/models.py b/various/autentizace/models.py new file mode 100644 index 00000000..6b7590f2 --- /dev/null +++ b/various/autentizace/models.py @@ -0,0 +1,27 @@ +# Nefunkční alternativa vestavěného Usera, který má jméno a mail v přidružené Osobě +# from django.contrib.auth.models import User as Django_User +# +# class Uzivatel(Django_User): +# class Meta: +# proxy = True +# +# @property +# def first_name(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().krestni_jmeno +# +# @property +# def last_name(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().prijmeni +# +# @property +# def email(self): +# osoby = Osoba.objects.filter(user=self) +# if len(osoby) == 0: +# return None +# return osoby.first().email \ No newline at end of file diff --git a/seminar/templates/seminar/profil/login.html b/various/autentizace/templates/autentizace/login.html similarity index 100% rename from seminar/templates/seminar/profil/login.html rename to various/autentizace/templates/autentizace/login.html diff --git a/seminar/templates/seminar/profil/logout.html b/various/autentizace/templates/autentizace/logout.html similarity index 100% rename from seminar/templates/seminar/profil/logout.html rename to various/autentizace/templates/autentizace/logout.html diff --git a/seminar/templates/seminar/registrace/nove_heslo.html b/various/autentizace/templates/autentizace/nove_heslo.html similarity index 100% rename from seminar/templates/seminar/registrace/nove_heslo.html rename to various/autentizace/templates/autentizace/nove_heslo.html diff --git a/seminar/templates/seminar/registrace/nove_nastaveno.html b/various/autentizace/templates/autentizace/nove_nastaveno.html similarity index 100% rename from seminar/templates/seminar/registrace/nove_nastaveno.html rename to various/autentizace/templates/autentizace/nove_nastaveno.html diff --git a/seminar/templates/seminar/registrace/password_reset_email.html b/various/autentizace/templates/autentizace/password_reset_email.html similarity index 100% rename from seminar/templates/seminar/registrace/password_reset_email.html rename to various/autentizace/templates/autentizace/password_reset_email.html diff --git a/seminar/templates/seminar/registrace/password_reset_subject.txt b/various/autentizace/templates/autentizace/password_reset_subject.txt similarity index 100% rename from seminar/templates/seminar/registrace/password_reset_subject.txt rename to various/autentizace/templates/autentizace/password_reset_subject.txt diff --git a/seminar/templates/seminar/registrace/reset_hesla.html b/various/autentizace/templates/autentizace/reset_hesla.html similarity index 100% rename from seminar/templates/seminar/registrace/reset_hesla.html rename to various/autentizace/templates/autentizace/reset_hesla.html diff --git a/seminar/templates/seminar/registrace/reset_poslan.html b/various/autentizace/templates/autentizace/reset_poslan.html similarity index 100% rename from seminar/templates/seminar/registrace/reset_poslan.html rename to various/autentizace/templates/autentizace/reset_poslan.html diff --git a/various/autentizace/urls.py b/various/autentizace/urls.py new file mode 100644 index 00000000..83c8e50e --- /dev/null +++ b/various/autentizace/urls.py @@ -0,0 +1,15 @@ +from django.urls import path +from . import views +from django.views.generic.base import RedirectView + +urlpatterns = [ + path('prihlasit/', views.LoginView.as_view(), name='login'), + path('login/', RedirectView.as_view(pattern_name='login', permanent=True, query_string=True)), + path('odhlasit/', views.LogoutView.as_view(), name='logout'), + path('logout/', RedirectView.as_view(pattern_name='logout', permanent=True, query_string=True)), + path('reset-hesla/', views.PasswordResetView.as_view(), name='reset_password'), + path('zmena-hesla/', views.PasswordChangeView.as_view(), name='change_password'), + path('reset-hesla/2/', views.PasswordResetDoneView.as_view(), name='reset_password_done'), + path('reset-hesla/potvrzeni///', views.PasswordResetConfirmView.as_view(), name='reset_password_confirm'), + path('reset-hesla/hotovo/', views.PasswordResetCompleteView.as_view(), name='reset_password_complete'), +] diff --git a/various/autentizace/utils.py b/various/autentizace/utils.py new file mode 100644 index 00000000..2341fbdd --- /dev/null +++ b/various/autentizace/utils.py @@ -0,0 +1,31 @@ +from django.contrib.auth.tokens import PasswordResetTokenGenerator +from django.contrib.sites.shortcuts import get_current_site +from django.urls import reverse_lazy +from django.utils.encoding import force_bytes +from django.utils.http import urlsafe_base64_encode + + +def posli_reset_hesla(u, request=None): + uid = urlsafe_base64_encode(force_bytes(u.pk)) + token = PasswordResetTokenGenerator().make_token(u) + url = "https://%s%s" % ( + str(get_current_site(request)), + str(reverse_lazy("reset_password_confirm", args=[uid, token])) + ) + + u.email_user( + subject="Vítej mezi řešiteli M&M!", + message="""Milý řešiteli, milá řešitelko, + +tvůj e-mail byl právě zaregistrován na mam.matfyz.cz. Heslo si prosím nastav na: %s + +Těšíme se na tvé příspěvky do našeho semináře, +Organizátoři M&M + +-- + +Tento e-mail byl vygenerován automaticky, chceš-li nás kontaktovat, napiš nám na adresu mam@matfyz.cz. +""" % url, + # TODO: templates/autentizace a django/contrib/auth/forms.py říkají, jak na to lépe + from_email="registrace@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? + ) \ No newline at end of file diff --git a/various/autentizace/views.py b/various/autentizace/views.py new file mode 100644 index 00000000..85ed3528 --- /dev/null +++ b/various/autentizace/views.py @@ -0,0 +1,45 @@ +from django.urls import reverse_lazy +from django.contrib.auth import views as auth_views + + +class LoginView(auth_views.LoginView): + # Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL + template_name = 'autentizace/login.html' + + +class LogoutView(auth_views.LogoutView): + # Jen vezmeme vestavěný a dáme mu vhodný template a přesměrovací URL + template_name = 'autentizace/logout.html' + # Pavel: Vůbec nevím, proč to s _lazy funguje, ale bez toho to bylo rozbité. + next_page = reverse_lazy('titulni_strana') + + +# Nejsem si jistý, který view co dostává, tak zahazuji všechny POSTy +class PasswordResetView(auth_views.PasswordResetView): + """ Chci resetovat heslo. """ + template_name = 'autentizace/reset_hesla.html' + success_url = reverse_lazy('reset_password_done') + from_email = 'login@mam.mff.cuni.cz' + email_template_name = 'autentizace/password_reset_email.html' + subject_template_name = 'autentizace/password_reset_subject.txt' + + +class PasswordResetDoneView(auth_views.PasswordResetDoneView): + """ Poslali jsme e-mail (pokud bylo kam)). """ + template_name = 'autentizace/reset_poslan.html' + + +class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): + """ Vymysli si heslo. """ + template_name = 'autentizace/nove_heslo.html' + success_url = reverse_lazy('reset_password_complete') + + +class PasswordResetCompleteView(auth_views.PasswordResetCompleteView): + """ Heslo se asi změnilo.""" + template_name = 'autentizace/nove_nastaveno.html' + + +class PasswordChangeView(auth_views.PasswordChangeView): + # template_name = 'seminar/password_change.html' + success_url = reverse_lazy('titulni_strana')