Passwort-zurücksetzen, Passwort-ändern, Account-löschen!
This commit is contained in:
@@ -6,11 +6,15 @@ from django import forms
|
|||||||
class RegisterForm(UserCreationForm):
|
class RegisterForm(UserCreationForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model=User
|
model=User
|
||||||
fields = ['username','password1','password2']
|
fields = ['username','password1','password2', "email"]
|
||||||
|
|
||||||
username = forms.CharField(
|
username = forms.CharField(
|
||||||
widget=forms.TextInput(attrs={'placeholder': 'BENUTZERNAME'})
|
widget=forms.TextInput(attrs={'placeholder': 'BENUTZERNAME'})
|
||||||
)
|
)
|
||||||
|
email = forms.EmailField(
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': 'E-MAIL'})
|
||||||
|
)
|
||||||
|
|
||||||
password1 = forms.CharField(
|
password1 = forms.CharField(
|
||||||
widget=forms.PasswordInput(attrs={'placeholder': 'PASSWORT'})
|
widget=forms.PasswordInput(attrs={'placeholder': 'PASSWORT'})
|
||||||
)
|
)
|
||||||
@@ -19,4 +23,3 @@ class RegisterForm(UserCreationForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
from django.urls import path # type: ignore
|
from django.urls import path, reverse_lazy # type: ignore
|
||||||
from . import views
|
from . import views
|
||||||
from django.contrib.auth.views import LogoutView
|
from django.contrib.auth.views import LogoutView
|
||||||
from django.contrib.auth.views import LoginView
|
from django.contrib.auth.views import LoginView
|
||||||
|
from django.contrib.auth import views as auth_views
|
||||||
|
|
||||||
app_name = 'accounts' # Namensraum zum verhindern von Konflikten zwischen Apps
|
app_name = 'accounts' # Namensraum zum verhindern von Konflikten zwischen Apps
|
||||||
#
|
#
|
||||||
@@ -13,4 +14,22 @@ urlpatterns = [
|
|||||||
path('logout/', LogoutView.as_view(next_page='accounts:login'), name='logout'),
|
path('logout/', LogoutView.as_view(next_page='accounts:login'), name='logout'),
|
||||||
path('login/', LoginView.as_view(template_name='accounts/login.html', next_page='accounts:home'), name='login'),
|
path('login/', LoginView.as_view(template_name='accounts/login.html', next_page='accounts:home'), name='login'),
|
||||||
path('register/', views.register, name='register'),
|
path('register/', views.register, name='register'),
|
||||||
|
path('password_reset/', auth_views.PasswordResetView.as_view(success_url=reverse_lazy('accounts:password_reset_done')), name='password_reset'),
|
||||||
|
path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(), name='password_reset_done'),
|
||||||
|
path('reset/done/', auth_views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
path('password_change/', views.password_changed, name='password_change'),
|
||||||
|
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),
|
||||||
|
path('delete_account/', views.deleteAccount, name="delete_account"),
|
||||||
|
path(
|
||||||
|
'reset/<uidb64>/<token>/',
|
||||||
|
auth_views.PasswordResetConfirmView.as_view(
|
||||||
|
template_name='registration/password_reset_confirm.html',
|
||||||
|
success_url=reverse_lazy('accounts:password_reset_complete')
|
||||||
|
),
|
||||||
|
name='password_reset_confirm'
|
||||||
|
),
|
||||||
|
|
||||||
]
|
]
|
||||||
@@ -2,7 +2,10 @@ from django.shortcuts import render, redirect
|
|||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth import login, authenticate
|
from django.contrib.auth import login, authenticate
|
||||||
from .forms import RegisterForm
|
from .forms import RegisterForm
|
||||||
|
from django.contrib.auth.forms import PasswordChangeForm
|
||||||
|
from django.contrib.auth import update_session_auth_hash
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth import logout
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
@login_required
|
@login_required
|
||||||
def home(request):
|
def home(request):
|
||||||
@@ -19,3 +22,33 @@ def register(response):
|
|||||||
form = RegisterForm()
|
form = RegisterForm()
|
||||||
|
|
||||||
return render(response, "accounts/register.html", {"form":form})
|
return render(response, "accounts/register.html", {"form":form})
|
||||||
|
|
||||||
|
from django.contrib.auth import views as auth_views
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def password_changed(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = PasswordChangeForm(user=request.user, data=request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
#user = form.save()
|
||||||
|
#update_session_auth_hash(request, user) #Hier wäre der User nach Passwortänderung noch angemeldet!
|
||||||
|
logout(request)
|
||||||
|
messages.success(request, "Das Passwort wurde erfolgreich geändert!")
|
||||||
|
return redirect('accounts:home')
|
||||||
|
|
||||||
|
else:
|
||||||
|
form = PasswordChangeForm(user=request.user)
|
||||||
|
|
||||||
|
return render(request, 'registration/password_change_form.html', {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def deleteAccount(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
user=request.user
|
||||||
|
logout(request)
|
||||||
|
user.delete()
|
||||||
|
messages.success(request, "Der Account wurde erfolgreich gelöscht!")
|
||||||
|
return redirect('homepage:home')
|
||||||
|
return render(request, 'registration/delete_account_confirm.html')
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from pathlib import Path
|
|||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' #TODO: NUR FÜR ENTWICKLUNG
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
|
||||||
|
|||||||
@@ -9,11 +9,15 @@
|
|||||||
|
|
||||||
<h1 class="text-center m-4 text-3xl lg:text-6xl">Willkommen, <b>{{ request.user.username }}</b>!</h1>
|
<h1 class="text-center m-4 text-3xl lg:text-6xl">Willkommen, <b>{{ request.user.username }}</b>!</h1>
|
||||||
|
|
||||||
|
|
||||||
<form action="{% url 'accounts:logout' %}" method="post">
|
<form action="{% url 'accounts:logout' %}" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<button class="bg-blue-600 text-white p-3 rounded-full font-black" type="submit">Abmelden</button>
|
<button class="bg-blue-600 text-white p-3 rounded-full font-black" type="submit">Abmelden</button>
|
||||||
</form>
|
</form>
|
||||||
|
<button class="text-center text-sm w-full mt-4 font-light text-blue-600"><a href="{% url 'accounts:password_change' %}">Passwort ändern</a></button>
|
||||||
|
<button class="text-center text-sm w-full mt-4 font-light text-red-600"><a href="{% url 'accounts:delete_account' %}">Account löschen</a></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<span class="text-[clamp(0.6rem,5vw,1rem)] font-black overflow-x-auto mt-1 ml-0.75 text-blue-600 p-0.75 bg-white">qivip
|
<span class="text-[clamp(0.6rem,5vw,1rem)] font-black overflow-x-auto mt-1 ml-0.75 text-blue-600 p-0.75 bg-white">qivip
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
<button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="submit" class="login-button">Anmelden</button>
|
<button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="submit" class="login-button">Anmelden</button>
|
||||||
</form>
|
</form>
|
||||||
<button class="text-center text-sm w-full mt-2 font-light text-blue-600"><a href="{% url 'accounts:register' %}" class="register_link">Noch kein Konto?</a></button>
|
<button class="text-center text-sm w-full mt-2 font-light text-blue-600"><a href="{% url 'accounts:register' %}" class="register_link">Noch kein Konto?</a></button>
|
||||||
|
<button class="text-center text-sm w-full mt-2 font-light text-blue-600"><a href="{% url 'accounts:password_reset' %}" class="register_link">Passwort zurücksetzen?</a></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -37,6 +37,11 @@
|
|||||||
{{ form.password2 }}
|
{{ form.password2 }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="register">
|
||||||
|
|
||||||
|
{{ form.email }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="submit" class="login-button">Registrieren</button>
|
<button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="submit" class="login-button">Registrieren</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
35
django/templates/registration/delete_account_confirm.html
Normal file
35
django/templates/registration/delete_account_confirm.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container mx-auto px-4">
|
||||||
|
<div class="max-w-lg mx-auto mt-10">
|
||||||
|
<div class="bg-white rounded-lg shadow-md p-6 border-blue-600 border-2 rounded-xl shadow-md">
|
||||||
|
<div class="text-center">
|
||||||
|
<svg class="mx-auto h-12 w-12 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<h2 class="mt-4 text-xl font-bold text-gray-900">Löschen bestätigen</h2>
|
||||||
|
|
||||||
|
<p class="mt-2 text-sm text-gray-600">
|
||||||
|
Möchten Sie ihren Account wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="post" class="mt-6">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="flex justify-center space-x-3">
|
||||||
|
<a href="{% url 'accounts:home' %}"
|
||||||
|
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
||||||
|
Abbrechen
|
||||||
|
</a>
|
||||||
|
<button type="submit"
|
||||||
|
class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500">
|
||||||
|
Löschen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
42
django/templates/registration/password_change_form.html
Normal file
42
django/templates/registration/password_change_form.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}Passwort ändern{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid place-content-center h-120 mt-12 mb-12 ">
|
||||||
|
<div class="w-80 p-4 m-2 border-blue-600 border-2 rounded-xl shadow-md lg:w-90">
|
||||||
|
<h2 class="text-2xl text-center p-4 font-black">Passwort ändern</h2>
|
||||||
|
<form class="space-y-4" method="post">
|
||||||
|
{% if form.errors %}
|
||||||
|
<div class=" items-center text-red-600 font-black overflow-x-auto break-words text-center">
|
||||||
|
<ul>
|
||||||
|
{% for field, errors in form.errors.items %}
|
||||||
|
{% for error in errors %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="register">
|
||||||
|
|
||||||
|
{{ form.old_password.label_tag }}
|
||||||
|
<input type="password" name="old_password" placeholder="ALTES PASSWORT" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="register">
|
||||||
|
{{ form.new_password1.label_tag }}
|
||||||
|
<input type="password" name="new_password1" placeholder="NEUES PASSWORT" />
|
||||||
|
</div>
|
||||||
|
<div class="register">
|
||||||
|
{{ form.new_password2.label_tag }}
|
||||||
|
<input type="password" name="new_password2" placeholder="NEUES PASSWORT WIEDERHOLEN" />
|
||||||
|
</div>
|
||||||
|
<button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="submit">Bestätigen</button>
|
||||||
|
<button class="text-center text-sm w-full mt-2 font-light text-blue-600"><a href="{% url 'accounts:home' %}" class="register_link">Doch nicht ändern?</a></button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
19
django/templates/registration/password_reset_complete.html
Normal file
19
django/templates/registration/password_reset_complete.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}Passwort zurückgesetzt{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid place-content-center h-120 mt-12 mb-12 ">
|
||||||
|
<div class="w-80 p-4 m-2 border-blue-600 border-2 rounded-xl shadow-md lg:w-90">
|
||||||
|
<h2 class="text-2xl text-center p-4 font-black">Passwort zurückgesetzt</h2>
|
||||||
|
<div class="space-y-4">
|
||||||
|
Das Passwort wurde erfolgreich zurückgesetzt! Sie können sich nun mit dem neuen Passwort anmelden!
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="mt-4">
|
||||||
|
<a href="{% url 'accounts:login' %}" class="register_link"><button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" class="login-button">anmelden</button></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
37
django/templates/registration/password_reset_confirm.html
Normal file
37
django/templates/registration/password_reset_confirm.html
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}Passwort zurücksetzen{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid place-content-center h-120 mt-12 mb-12 ">
|
||||||
|
<div class="w-80 p-4 m-2 border-blue-600 border-2 rounded-xl shadow-md lg:w-90">
|
||||||
|
<h2 class="text-2xl text-center p-4 font-black">Passwort zurücksetzen</h2>
|
||||||
|
<form class="space-y-4" method="post">
|
||||||
|
{% if form.errors %}
|
||||||
|
<div class=" items-center text-red-600 font-black overflow-x-auto break-words text-center">
|
||||||
|
<ul>
|
||||||
|
{% for field, errors in form.errors.items %}
|
||||||
|
{% for error in errors %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<div class="register">
|
||||||
|
{{ form.new_password1.label_tag }}
|
||||||
|
<input type="password" name="new_password1" placeholder="NEUES PASSWORT" />
|
||||||
|
</div>
|
||||||
|
<div class="register">
|
||||||
|
{{ form.new_password2.label_tag }}
|
||||||
|
<input type="password" name="new_password2" placeholder="NEUES PASSWORT WIEDERHOLEN" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="submit">Bestätigen</button>
|
||||||
|
<button class="text-center text-sm w-full mt-2 font-light text-blue-600"><a href="{% url 'accounts:home' %}" class="register_link">Doch nicht zurücksetzen?</a></button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
18
django/templates/registration/password_reset_done.html
Normal file
18
django/templates/registration/password_reset_done.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}E-Mail gesendet{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid place-content-center h-120 mt-12 mb-12">
|
||||||
|
<div class="w-80 p-6 m-2 border-blue-600 border-2 rounded-xl shadow-md lg:w-90 text-center">
|
||||||
|
<h2 class="text-2xl font-black mb-4">E-Mail wurde gesendet</h2>
|
||||||
|
<p class="text-gray-700 mb-6">
|
||||||
|
Wenn ein Konto mit dieser E-Mail-Adresse existiert, haben wir dir eine Nachricht mit einem Link zum Zurücksetzen des Passworts gesendet.
|
||||||
|
|
||||||
|
</p><p class="text-gray-700 mb-6 font-bold"> Tipp: Gegebenenfalls Spam überprüfen.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<a href="{% url 'accounts:login' %}" class="block w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200">Zur Anmeldung</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
11
django/templates/registration/password_reset_email.html
Normal file
11
django/templates/registration/password_reset_email.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
{% autoescape off %}
|
||||||
|
{% blocktranslate %}Du erhältst diese E-Mail, weil du einen Passwort-Zurücksetzungsversuch bei {{ site_name }} angefragt hast.{% endblocktranslate %}
|
||||||
|
|
||||||
|
{% translate "Bitte gehe zu folgender Seite und wähle ein neues Passwort:" %}
|
||||||
|
{{ protocol }}://{{ domain }}{% url 'accounts:password_reset_confirm' uidb64=uid token=token %}
|
||||||
|
|
||||||
|
{% translate "Dein Benutzername ist:" %} {{ user.get_username }}
|
||||||
|
|
||||||
|
{% blocktranslate %}Danke, dass du {{ site_name }} benutzt!{% endblocktranslate %}
|
||||||
|
{% endautoescape %}
|
||||||
35
django/templates/registration/password_reset_form.html
Normal file
35
django/templates/registration/password_reset_form.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}Passwort ändern{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid place-content-center h-120 mt-12 mb-12 ">
|
||||||
|
<div class="w-80 p-4 m-2 border-blue-600 border-2 rounded-xl shadow-md lg:w-90">
|
||||||
|
<h2 class="text-2xl text-center p-4 font-black">Passwort zurücksetzen</h2>
|
||||||
|
<form class="space-y-4" method="post">
|
||||||
|
Gib hier deine E-Mail an und erhalte eine E-Mail, um das Passwort zurückzusetzen.
|
||||||
|
{% if form.errors %}
|
||||||
|
<div class=" items-center text-red-600 font-black overflow-x-auto break-words text-center">
|
||||||
|
<ul>
|
||||||
|
{% for field, errors in form.errors.items %}
|
||||||
|
{% for error in errors %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="register">
|
||||||
|
{{ form.email.label_tag }}
|
||||||
|
<input type="email" name="email" placeholder="E-MAIL" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<button class="w-full p-3 rounded-full bg-blue-600 text-white font-black hover:scale-105 transition duration-200" type="submit">Bestätigen</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user