Refactor: split code into several django apps (we call them modules).
This commit is contained in:
1
dav_auth/__init__.py
Normal file
1
dav_auth/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
default_app_config = 'dav_auth.apps.AppConfig'
|
||||
12
dav_auth/apps.py
Normal file
12
dav_auth/apps.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from dav_base.config.apps import AppConfig as _AppConfig, DefaultSetting
|
||||
|
||||
DEFAULT_SETTINGS = (
|
||||
DefaultSetting('login_redirect_url', 'root'),
|
||||
DefaultSetting('logout_redirect_url', 'root'),
|
||||
)
|
||||
|
||||
|
||||
class AppConfig(_AppConfig):
|
||||
name = 'dav_auth'
|
||||
verbose_name = u'DAV Benutzerverwaltung'
|
||||
default_settings = DEFAULT_SETTINGS
|
||||
2
dav_auth/django_project_config/settings-dav_auth.py
Normal file
2
dav_auth/django_project_config/settings-dav_auth.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# LOGIN_REDIRECT_URL = 'root'
|
||||
# LOGOUT_REDIRECT_URL = 'root'
|
||||
25
dav_auth/emails.py
Normal file
25
dav_auth/emails.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from dav_base.emails import AbstractMail
|
||||
|
||||
|
||||
class PasswordSetEmail(AbstractMail):
|
||||
_subject = u'Zugangsdaten'
|
||||
_template_name = 'dav_auth/emails/password_set.txt'
|
||||
|
||||
def __init__(self, user, password):
|
||||
self._user = user
|
||||
self._password = password
|
||||
|
||||
def _get_recipients(self):
|
||||
r = u'{fullname} <{email}>'.format(fullname=self._user.get_full_name(),
|
||||
email=self._user.email)
|
||||
return [r]
|
||||
|
||||
def _get_context_data(self, extra_context=None):
|
||||
context = super(PasswordSetEmail, self)._get_context_data(extra_context=extra_context)
|
||||
context.update({
|
||||
'fullname': self._user.get_full_name(),
|
||||
'username': self._user.username,
|
||||
'password': self._password
|
||||
})
|
||||
return context
|
||||
76
dav_auth/forms.py
Normal file
76
dav_auth/forms.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
from django import forms
|
||||
from django.contrib.auth import forms as auth_forms, password_validation
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LoginForm(auth_forms.AuthenticationForm):
|
||||
username = auth_forms.UsernameField(
|
||||
max_length=254,
|
||||
label=_(u'E-Mail-Adresse'),
|
||||
widget=forms.TextInput(attrs={'autofocus': True}),
|
||||
)
|
||||
|
||||
error_messages = {
|
||||
'invalid_login': _(u'Benutzername oder Passwort falsch.'),
|
||||
'inactive': _("This account is inactive."),
|
||||
}
|
||||
|
||||
def clean_username(self):
|
||||
username = self.cleaned_data.get('username')
|
||||
return username.lower()
|
||||
|
||||
|
||||
class SetPasswordForm(forms.Form):
|
||||
new_password = forms.CharField(max_length=12,
|
||||
label=_(u'Neues Passwort'),
|
||||
widget=forms.PasswordInput)
|
||||
new_password_repeat = forms.CharField(max_length=12,
|
||||
label=_(u'Neues Passwort wiederholen'),
|
||||
widget=forms.PasswordInput)
|
||||
send_password_mail = forms.BooleanField(required=False,
|
||||
initial=False,
|
||||
label=_(u'Neues Passwort per E-Mail zusenden'),
|
||||
)
|
||||
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
self.user = user
|
||||
super(SetPasswordForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def clean_new_password(self):
|
||||
password = self.cleaned_data.get('new_password')
|
||||
password_validation.validate_password(password, self.user)
|
||||
return password
|
||||
|
||||
def clean_new_password_repeat(self):
|
||||
password1 = self.cleaned_data.get('new_password')
|
||||
password2 = self.cleaned_data.get('new_password_repeat')
|
||||
if password1 and password2:
|
||||
if password1 != password2:
|
||||
raise forms.ValidationError(
|
||||
ugettext(u'Passwörter stimmen nicht überein'),
|
||||
code='password_mismatch',
|
||||
)
|
||||
return password2
|
||||
|
||||
def save(self, commit=True):
|
||||
new_password = self.cleaned_data.get('new_password')
|
||||
self.user.set_password(new_password)
|
||||
if commit:
|
||||
self.user.save()
|
||||
return self.user
|
||||
|
||||
|
||||
class ResetPasswordForm(forms.Form):
|
||||
username = auth_forms.UsernameField(
|
||||
max_length=254,
|
||||
label=_(u'E-Mail-Adresse'),
|
||||
widget=forms.TextInput(attrs={'autofocus': True}),
|
||||
)
|
||||
|
||||
def clean_username(self):
|
||||
username = self.cleaned_data.get('username')
|
||||
return username.lower()
|
||||
3
dav_auth/module.json
Normal file
3
dav_auth/module.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"url_prefix": "auth"
|
||||
}
|
||||
1
dav_auth/templates/dav_auth/base.html
Normal file
1
dav_auth/templates/dav_auth/base.html
Normal file
@@ -0,0 +1 @@
|
||||
{% extends "dav_base/base.html" %}
|
||||
6
dav_auth/templates/dav_auth/emails/password_set.txt
Normal file
6
dav_auth/templates/dav_auth/emails/password_set.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Hallo {{ fullname }},
|
||||
|
||||
Benutzername: {{ username }}
|
||||
Passwort: {{ password }}
|
||||
|
||||
URL: {{ base_url }}{% url 'root' %}
|
||||
36
dav_auth/templates/dav_auth/forms/login.html
Normal file
36
dav_auth/templates/dav_auth/forms/login.html
Normal file
@@ -0,0 +1,36 @@
|
||||
{% extends "dav_auth/base.html" %}
|
||||
{% load bootstrap3 %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block head-title %}{% trans 'Login' %} - {{ block.super }}{% endblock head-title %}
|
||||
|
||||
{% block page-container %}
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<h3>{% trans 'Login' %}</h3>
|
||||
<div class="well">
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
<div class="pull-right"><a href="{% url 'dav_auth:reset_password' %}">{% trans 'Passwort vergessen?' %}</a></div>
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn btn-success">
|
||||
{% bootstrap_icon 'log-in' %} 
|
||||
{% trans 'Login' %}
|
||||
</button>
|
||||
<a class="btn btn-danger" href="{% url 'root' %}">
|
||||
{% bootstrap_icon 'remove' %} 
|
||||
{% trans 'Abbrechen' %}
|
||||
</a>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page-container %}
|
||||
35
dav_auth/templates/dav_auth/forms/reset_password.html
Normal file
35
dav_auth/templates/dav_auth/forms/reset_password.html
Normal file
@@ -0,0 +1,35 @@
|
||||
{% extends "dav_auth/base.html" %}
|
||||
{% load bootstrap3 %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block head-title %}{% trans 'Passwort vergessen?' %} - {{ block.super }}{% endblock head-title %}
|
||||
|
||||
{% block page-container %}
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<h3>{% trans 'Passwort vergessen?' %}</h3>
|
||||
<div class="well">
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn btn-success">
|
||||
{% bootstrap_icon 'saved' %} 
|
||||
{% trans 'Neues Passwort per E-Mail zusenden' %}
|
||||
</button>
|
||||
<a class="btn btn-danger" href="{% url 'root' %}">
|
||||
{% bootstrap_icon 'remove' %} 
|
||||
{% trans 'Abbrechen' %}
|
||||
</a>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page-container %}
|
||||
35
dav_auth/templates/dav_auth/forms/set_password.html
Normal file
35
dav_auth/templates/dav_auth/forms/set_password.html
Normal file
@@ -0,0 +1,35 @@
|
||||
{% extends "dav_auth/base.html" %}
|
||||
{% load bootstrap3 %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block head-title %}{% trans 'Neues Passwort setzen' %} - {{ user }} - {{ block.super }}{% endblock head-title %}
|
||||
|
||||
{% block page-container %}
|
||||
<div class="row">
|
||||
<div class="col-sm-2">
|
||||
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<h3>{% trans 'Neues Passwort setzen' %}</h3>
|
||||
<div class="well">
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn btn-success">
|
||||
{% bootstrap_icon 'saved' %} 
|
||||
{% trans 'Neues Passwort setzen' %}
|
||||
</button>
|
||||
<a class="btn btn-danger" href="{% url 'root' %}">
|
||||
{% bootstrap_icon 'remove' %} 
|
||||
{% trans 'Abbrechen' %}
|
||||
</a>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock page-container %}
|
||||
19
dav_auth/templates/dav_auth/includes/login_widget.html
Normal file
19
dav_auth/templates/dav_auth/includes/login_widget.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{% load bootstrap3 %}
|
||||
{% load i18n %}
|
||||
{% if user.is_authenticated %}
|
||||
<div class="dropdown">
|
||||
<button type="button" id="user_dropdown_button" class="btn btn-default btn-sm dropdown-toggle"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
{{ user }} <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="user_dropdown_button">
|
||||
<li><a href="{% url 'dav_auth:set_password' %}">{% trans 'Passwort ändern' %}</a></li>
|
||||
<li><a href="{% url 'dav_auth:logout' %}">{% trans 'Logout' %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% else %}
|
||||
<a class="btn btn-default btn-sm" href="{% url 'dav_auth:login' %}">
|
||||
{% bootstrap_icon 'log-in' %}
|
||||
{% trans 'Login' %}
|
||||
</a>
|
||||
{% endif %}
|
||||
10
dav_auth/urls.py
Normal file
10
dav_auth/urls.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^login$', views.LoginView.as_view(), name='login'),
|
||||
url(r'^logout$', views.LogoutView.as_view(), name='logout'),
|
||||
url(r'^password$', views.SetPasswordView.as_view(), name='set_password'),
|
||||
url(r'^password/reset$', views.ResetPasswordView.as_view(), name='reset_password'),
|
||||
]
|
||||
82
dav_auth/views.py
Normal file
82
dav_auth/views.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import logging
|
||||
from django.apps import apps
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import views as auth_views, get_user_model
|
||||
from django.shortcuts import resolve_url
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views import generic
|
||||
|
||||
from . import emails
|
||||
from . import forms
|
||||
|
||||
app_config = apps.get_containing_app_config(__package__)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LoginView(auth_views.LoginView):
|
||||
form_class = forms.LoginForm
|
||||
template_name = 'dav_auth/forms/login.html'
|
||||
|
||||
def get_redirect_url(self):
|
||||
url = super(LoginView, self).get_redirect_url()
|
||||
if not url and app_config.settings.login_redirect_url:
|
||||
url = resolve_url(app_config.settings.login_redirect_url)
|
||||
return url
|
||||
|
||||
def form_valid(self, form):
|
||||
r = super(LoginView, self).form_valid(form)
|
||||
messages.success(self.request, _(u'Benutzer angemeldet: %(username)s') % {'username': form.get_user()})
|
||||
return r
|
||||
|
||||
|
||||
class LogoutView(auth_views.LogoutView):
|
||||
def get_next_page(self):
|
||||
url = super(LogoutView, self).get_next_page()
|
||||
if not url and app_config.settings.logout_redirect_url:
|
||||
url = resolve_url(app_config.settings.logout_redirect_url)
|
||||
return url
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
r = super(LogoutView, self).dispatch(request, *args, **kwargs)
|
||||
messages.success(self.request, _(u'Benutzer abgemeldet.'))
|
||||
return r
|
||||
|
||||
|
||||
class SetPasswordView(auth_views.PasswordChangeView):
|
||||
form_class = forms.SetPasswordForm
|
||||
template_name = 'dav_auth/forms/set_password.html'
|
||||
|
||||
def get_success_url(self):
|
||||
return resolve_url(app_config.settings.login_redirect_url)
|
||||
|
||||
def form_valid(self, form):
|
||||
r = super(SetPasswordView, self).form_valid(form)
|
||||
messages.success(self.request, _(u'Passwort gespeichert.'))
|
||||
if form.cleaned_data.get('send_password_mail', False):
|
||||
email = emails.PasswordSetEmail(self.request.user, form.cleaned_data['new_password'])
|
||||
email.send()
|
||||
return r
|
||||
|
||||
|
||||
class ResetPasswordView(generic.FormView):
|
||||
form_class = forms.ResetPasswordForm
|
||||
template_name = 'dav_auth/forms/reset_password.html'
|
||||
success_url = reverse_lazy('dav_auth:login')
|
||||
|
||||
def form_valid(self, form):
|
||||
username = form.cleaned_data.get('username')
|
||||
user_model = get_user_model()
|
||||
try:
|
||||
user = user_model.objects.get(username=username)
|
||||
random_password = user_model.objects.make_random_password(length=12)
|
||||
user.set_password(random_password)
|
||||
user.save()
|
||||
email = emails.PasswordSetEmail(user, random_password)
|
||||
email.send()
|
||||
messages.success(self.request, _(u'Neues Passwort versendet.'))
|
||||
logger.info('Password reset for user \'%s\'', username)
|
||||
except user_model.DoesNotExist:
|
||||
logger.warning('Password reset for unknown user \'%s\'', username)
|
||||
|
||||
return super(ResetPasswordView, self).form_valid(form)
|
||||
Reference in New Issue
Block a user