Browse Source

Add Generování hesla v registraci.

middleware_test
Jonas Havelka 3 years ago
parent
commit
8572264845
  1. 13
      seminar/forms.py
  2. 4
      seminar/templates/seminar/profil/prihlaska.html
  3. 81
      seminar/views/views_all.py

13
seminar/forms.py

@ -1,5 +1,6 @@
from django import forms from django import forms
from dal import autocomplete from dal import autocomplete
from django.contrib.auth.forms import PasswordResetForm
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.forms import formset_factory from django.forms import formset_factory
@ -37,21 +38,11 @@ class LoginForm(forms.Form):
widget=forms.PasswordInput()) widget=forms.PasswordInput())
class PrihlaskaForm(forms.Form): class PrihlaskaForm(PasswordResetForm):
username = forms.CharField(label='Přihlašovací jméno', username = forms.CharField(label='Přihlašovací jméno',
max_length=256, max_length=256,
required=True, required=True,
help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři') help_text='Tímto jménem se následně budeš přihlašovat pro odevzdání řešení a další činnosti v semináři')
password = forms.CharField(
label='Heslo',
max_length=256,
required=True,
widget=forms.PasswordInput())
password_check = forms.CharField(
label='Ověření hesla',
max_length=256,
required=True,
widget=forms.PasswordInput())
jmeno = forms.CharField(label='Jméno', max_length=256, required=True) jmeno = forms.CharField(label='Jméno', max_length=256, required=True)
prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True)

4
seminar/templates/seminar/profil/prihlaska.html

@ -33,8 +33,8 @@
</h4> </h4>
<table class="form"> <table class="form">
{% include "seminar/profil/prihlaska_field.html" with field=form.username %} {% include "seminar/profil/prihlaska_field.html" with field=form.username %}
{% include "seminar/profil/prihlaska_field.html" with field=form.password %} {# {% include "seminar/profil/prihlaska_field.html" with field=form.password %}#}
{% include "seminar/profil/prihlaska_field.html" with field=form.password_check %} {# {% include "seminar/profil/prihlaska_field.html" with field=form.password_check %}#}
</table> </table>
<hr> <hr>

81
seminar/views/views_all.py

@ -1,10 +1,12 @@
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.shortcuts import get_object_or_404, render, redirect
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, JsonResponse
from django.urls import reverse,reverse_lazy from django.urls import reverse,reverse_lazy
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist from django.core.exceptions import PermissionDenied, ObjectDoesNotExist
from django.core.mail import send_mail 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.views import generic
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect from django.http import Http404,HttpResponseBadRequest,HttpResponseRedirect
@ -79,7 +81,7 @@ class ObalkovaniView(generic.ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ObalkovaniView, self).get_context_data(**kwargs) context = super(ObalkovaniView, self).get_context_data(**kwargs)
print(self.cislo) print(self.cislo)
context['cislo'] = self.cislo context['cislo'] = self.cislo
return context return context
class TNLData(object): class TNLData(object):
@ -97,7 +99,7 @@ class TNLData(object):
self.tema_in_path = True self.tema_in_path = True
def add_edit_options(self): def add_edit_options(self):
self.deletable = tnltt.deletable(self) self.deletable = tnltt.deletable(self)
self.editable_siblings = tnltt.editableSiblings(self) self.editable_siblings = tnltt.editableSiblings(self)
self.editable_children = tnltt.editableChildren(self) self.editable_children = tnltt.editableChildren(self)
self.text_only_subtree = tnltt.textOnlySubtree(self) self.text_only_subtree = tnltt.textOnlySubtree(self)
@ -117,7 +119,7 @@ class TNLData(object):
while True: while True:
rocnik = isinstance(parent, s.RocnikNode) rocnik = isinstance(parent, s.RocnikNode)
cislo = isinstance(parent, s.CisloNode) cislo = isinstance(parent, s.CisloNode)
uloha = (isinstance(parent, s.UlohaVzorakNode) or uloha = (isinstance(parent, s.UlohaVzorakNode) or
isinstance(parent, s.UlohaZadaniNode)) isinstance(parent, s.UlohaZadaniNode))
tema = isinstance(parent, s.TemaVCisleNode) tema = isinstance(parent, s.TemaVCisleNode)
@ -137,7 +139,7 @@ class TNLData(object):
print("Existuje TreeNode, který není pod číslem, ročníkem, úlohou" print("Existuje TreeNode, který není pod číslem, ročníkem, úlohou"
"ani tématem. {}".format(anode)) "ani tématem. {}".format(anode))
return False return False
@classmethod @classmethod
def all_public_children(cls, anode): def all_public_children(cls, anode):
for ch in treelib.all_children(anode): for ch in treelib.all_children(anode):
@ -156,14 +158,14 @@ class TNLData(object):
if user.has_perm('auth.org'): if user.has_perm('auth.org'):
enum_children = enumerate(treelib.all_children(anode)) enum_children = enumerate(treelib.all_children(anode))
else: else:
enum_children = enumerate(TNLData.all_public_children(anode)) enum_children = enumerate(TNLData.all_public_children(anode))
for (idx,ch) in enum_children: for (idx,ch) in enum_children:
outitem = cls.from_treenode(ch, user, out, idx) outitem = cls.from_treenode(ch, user, out, idx)
out.children.append(outitem) out.children.append(outitem)
out.add_edit_options() out.add_edit_options()
return out return out
@classmethod @classmethod
def from_tnldata_list(cls, tnllist): def from_tnldata_list(cls, tnllist):
"""Vyrobíme virtuální TNL, který nemá obsah, ale má za potomky všechna zadaná TNLData""" """Vyrobíme virtuální TNL, který nemá obsah, ale má za potomky všechna zadaná TNLData"""
@ -192,7 +194,7 @@ class TNLData(object):
for tnl in result: for tnl in result:
found.append(tnl) found.append(tnl)
return found return found
def to_json(self): def to_json(self):
#self.node = anode #self.node = anode
#self.children = [] #self.children = []
@ -264,7 +266,7 @@ class TreeNodePridatView(generic.View):
if kam not in ('pred','syn','za'): if kam not in ('pred','syn','za'):
raise ValidationError('Přidat lze pouze před nebo za node nebo jako syna') raise ValidationError('Přidat lze pouze před nebo za node nebo jako syna')
if co == m.TextNode: if co == m.TextNode:
new_obj = m.Text() new_obj = m.Text()
new_obj.save() new_obj.save()
@ -303,7 +305,7 @@ class TreeNodePridatView(generic.View):
node = treelib.create_node_after(node,typ) node = treelib.create_node_after(node,typ)
return redirect(node.get_admin_url()) return redirect(node.get_admin_url())
class TreeNodeSmazatView(generic.base.View): class TreeNodeSmazatView(generic.base.View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
@ -343,7 +345,7 @@ class TreeNodeProhoditView(generic.base.View):
class SirotcinecView(generic.ListView): class SirotcinecView(generic.ListView):
model = s.TreeNode model = s.TreeNode
template_name = 'seminar/orphanage.html' template_name = 'seminar/orphanage.html'
def get_queryset(self): def get_queryset(self):
return s.TreeNode.objects.not_instance_of(s.RocnikNode).filter(root=None,prev=None,succ=None,father_of_first=None) return s.TreeNode.objects.not_instance_of(s.RocnikNode).filter(root=None,prev=None,succ=None,father_of_first=None)
@ -548,7 +550,7 @@ class TitulniStranaView(generic.ListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(TitulniStranaView, self).get_context_data(**kwargs) context = super(TitulniStranaView, self).get_context_data(**kwargs)
nastaveni = get_object_or_404(Nastaveni) nastaveni = get_object_or_404(Nastaveni)
deadline_soustredeni = (nastaveni.aktualni_cislo.datum_deadline_soustredeni, "soustredeni") deadline_soustredeni = (nastaveni.aktualni_cislo.datum_deadline_soustredeni, "soustredeni")
preddeadline = (nastaveni.aktualni_cislo.datum_preddeadline, "preddeadline") preddeadline = (nastaveni.aktualni_cislo.datum_preddeadline, "preddeadline")
deadline = (nastaveni.aktualni_cislo.datum_deadline, "deadline") deadline = (nastaveni.aktualni_cislo.datum_deadline, "deadline")
@ -564,7 +566,7 @@ class TitulniStranaView(generic.ListView):
context['nejblizsi_deadline'] = datetime.combine(nejblizsi_deadline[0], datetime.max.time()) context['nejblizsi_deadline'] = datetime.combine(nejblizsi_deadline[0], datetime.max.time())
else: else:
context['nejblizsi_deadline'] = None context['nejblizsi_deadline'] = None
context['typ_deadline'] = nejblizsi_deadline[1] context['typ_deadline'] = nejblizsi_deadline[1]
# Aktuální témata # Aktuální témata
@ -637,10 +639,10 @@ class ArchivView(generic.ListView):
urls[c.rocnik] = c.titulka_nahled.url urls[c.rocnik] = c.titulka_nahled.url
context["object_list"] = urls context["object_list"] = urls
return context return context
@ -762,7 +764,7 @@ class OdmenyView(generic.TemplateView):
outlist.append({'jmeno': resitel.osoba.plne_jmeno(), 'ftitul': ftitul, 'ttitul': ttitul}) outlist.append({'jmeno': resitel.osoba.plne_jmeno(), 'ftitul': ftitul, 'ttitul': ttitul})
context['zmeny'] = outlist context['zmeny'] = outlist
return context return context
@ -852,7 +854,7 @@ class OrgoRozcestnikView(TemplateView):
os = s.Osoba.objects.get(user=u) os = s.Osoba.objects.get(user=u)
organizator = s.Organizator.objects.get(osoba=os) organizator = s.Organizator.objects.get(osoba=os)
#FIXME: přidat stav='STAV_ZADANY' #FIXME: přidat stav='STAV_ZADANY'
temata = s.Tema.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), temata = s.Tema.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]),
rocnik=aktualni_rocnik).distinct() rocnik=aktualni_rocnik).distinct()
ulohy = s.Uloha.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]), ulohy = s.Uloha.objects.filter(Q(garant=organizator) | Q(autor=organizator) | Q(opravovatele__in=[organizator]),
cislo_zadani__rocnik=aktualni_rocnik).distinct() cislo_zadani__rocnik=aktualni_rocnik).distinct()
@ -877,7 +879,7 @@ def TitulyView(request, rocnik, cislo):
cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, poradi = cislo) cislo_obj = Cislo.objects.get(rocnik = rocnik_obj, poradi = cislo)
asciijmena = [] asciijmena = []
jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka), jmenovci = False # detekuje, zda jsou dva řešitelé jmenovci (modulo nabodeníčka),
# pokud ano, vrátí se jako true # pokud ano, vrátí se jako true
slovnik_s_body = body_resitelu(resitele, rocnik_obj) slovnik_s_body = body_resitelu(resitele, rocnik_obj)
@ -893,7 +895,7 @@ def TitulyView(request, rocnik, cislo):
asciijmena.append(resitel.ascii) asciijmena.append(resitel.ascii)
else: else:
jmenovci = True jmenovci = True
return render(request, 'seminar/archiv/tituly.tex', return render(request, 'seminar/archiv/tituly.tex',
{'resitele': resitele,'jmenovci':jmenovci},content_type="text/plain") {'resitele': resitele,'jmenovci':jmenovci},content_type="text/plain")
@ -966,7 +968,7 @@ def group_by_rocnik(clanky):
rocnik = clanek.cislo.rocnik.rocnik rocnik = clanek.cislo.rocnik.rocnik
skupiny_clanku.append(skupina) skupiny_clanku.append(skupina)
return skupiny_clanku return skupiny_clanku
# FIXME: clanky jsou vsechny, pokud budou i neresitelske, tak se take zobrazi # FIXME: clanky jsou vsechny, pokud budou i neresitelske, tak se take zobrazi
# FIXME: Původně tu byl kód přímo v těle třídy, což rozbíjelo migrace. Opravil jsem, ale vůbec nevím, jestli to funguje. # FIXME: Původně tu byl kód přímo v těle třídy, což rozbíjelo migrace. Opravil jsem, ale vůbec nevím, jestli to funguje.
@ -1055,9 +1057,9 @@ class NahrajReseniView(LoginRequiredMixin, CreateView):
def get_context_data(self,**kwargs): def get_context_data(self,**kwargs):
data = super().get_context_data(**kwargs) data = super().get_context_data(**kwargs)
if self.request.POST: if self.request.POST:
data['prilohy'] = f.ReseniSPrilohamiFormSet(self.request.POST,self.request.FILES) data['prilohy'] = f.ReseniSPrilohamiFormSet(self.request.POST,self.request.FILES)
else: else:
data['prilohy'] = f.ReseniSPrilohamiFormSet() data['prilohy'] = f.ReseniSPrilohamiFormSet()
return data return data
# FIXME prepsat tak, aby form_valid se volalo jen tehdy, kdyz je form i formset validni # FIXME prepsat tak, aby form_valid se volalo jen tehdy, kdyz je form i formset validni
@ -1070,13 +1072,13 @@ class NahrajReseniView(LoginRequiredMixin, CreateView):
with transaction.atomic(): with transaction.atomic():
self.object = form.save() self.object = form.save()
self.object.resitele.add(Resitel.objects.get(osoba__user = self.request.user)) self.object.resitele.add(Resitel.objects.get(osoba__user = self.request.user))
self.object.cas_doruceni = timezone.now() self.object.cas_doruceni = timezone.now()
self.object.forma = s.Reseni.FORMA_UPLOAD self.object.forma = s.Reseni.FORMA_UPLOAD
self.object.save() self.object.save()
prilohy.instance = self.object prilohy.instance = self.object
prilohy.save() prilohy.save()
# Pošleme mail opravovatelům a garantovi # Pošleme mail opravovatelům a garantovi
# FIXME: Nechat spočítat databázi? Je to pár dotazů (pravděpodobně), takže to za to možná nestojí # FIXME: Nechat spočítat databázi? Je to pár dotazů (pravděpodobně), takže to za to možná nestojí
prijemci = set() prijemci = set()
@ -1099,7 +1101,7 @@ class NahrajReseniView(LoginRequiredMixin, CreateView):
def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data): def prihlaska_log_gdpr_safe(logger, gdpr_logger, msg, form_data):
msg = "{}, form_hash:{}".format(msg,hash(frozenset(form_data.items))) msg = "{}, form_hash:{}".format(msg,hash(frozenset(form_data.items)))
logger.warn(msg) logger.warn(msg)
gdpr_logger.warn(msg+", form:{}".format(form_data)) gdpr_logger.warn(msg+", form:{}".format(form_data))
from django.forms.models import model_to_dict from django.forms.models import model_to_dict
def resitelEditView(request): def resitelEditView(request):
@ -1185,11 +1187,10 @@ def prihlaskaView(request):
fcd = form.cleaned_data fcd = form.cleaned_data
form_hash = hash(frozenset(fcd.items())) form_hash = hash(frozenset(fcd.items()))
form_logger.info(str(fcd) + str(form_hash)) # TODO možná logovat jinak form_logger.info(str(fcd) + str(form_hash)) # TODO možná logovat jinak
with transaction.atomic(): with transaction.atomic():
u = User.objects.create_user( u = User.objects.create_user(
username=fcd['username'], username=fcd['username'],
password=fcd['password'],
email = fcd['email']) email = fcd['email'])
u.save() u.save()
resitel_perm = Permission.objects.filter(codename__exact='resitel').first() resitel_perm = Permission.objects.filter(codename__exact='resitel').first()
@ -1229,7 +1230,7 @@ def prihlaskaView(request):
zasilat = fcd['zasilat'], zasilat = fcd['zasilat'],
zasilat_cislo_emailem = fcd['zasilat_cislo_emailem'] zasilat_cislo_emailem = fcd['zasilat_cislo_emailem']
) )
r.save() r.save()
r.osoba = o r.osoba = o
if fcd.get('skola'): if fcd.get('skola'):
@ -1240,11 +1241,19 @@ def prihlaskaView(request):
err_logger.warn(msg + str(form_hash)) err_logger.warn(msg + str(form_hash))
r.save() r.save()
send_mail( 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("password_reset_confirm", args=[uid, token]))
)
u.email_user(
subject="Registrace na M&M", subject="Registrace na M&M",
message=f"Tento e-mail byl právě zaregistrován na mam.matfyz.cz.", # TODO: Dovymyslet text. message=f"Tento e-mail byl právě zaregistrován na mam.matfyz.cz. Nové heslo si nastavíš na: " + url,
# TODO: templates/seminar/registrace a django/contrib/auth/forms.py říkají, jak na to lépe
# TODO: Dovymyslet text.
from_email="registrace@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? from_email="registrace@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení?
recipient_list=list([fcd['email']]),
) )
return formularOKView(request) return formularOKView(request)
@ -1319,7 +1328,7 @@ class NahrajObrazekKTreeNoduView(LoginRequiredMixin, CreateView):
return JsonResponse({"url":self.object.na_web.url}) return JsonResponse({"url":self.object.na_web.url})
# Jen hloupé rozhazovátko # Jen hloupé rozhazovátko
def profilView(request): def profilView(request):
@ -1345,10 +1354,10 @@ def formularOKView(request):
return render(request, template_name, context) return render(request, template_name, context)
#------------------ Jak řešit - možná má být udělané úplně jinak #------------------ Jak řešit - možná má být udělané úplně jinak
class JakResitView(generic.ListView): class JakResitView(generic.ListView):
template_name = 'seminar/jak-resit.html' template_name = 'seminar/jak-resit.html'
def get_queryset(self): def get_queryset(self):
return None return None

Loading…
Cancel
Save