From 7a2adbf990df5b497411f51e51d26aae290c70f1 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Mon, 10 Feb 2014 15:28:02 +0100 Subject: [PATCH] unusable passwords - support for all djangos --- portal/django_passresetview.py | 4 ++-- portal/forms.py | 24 +++++++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/portal/django_passresetview.py b/portal/django_passresetview.py index 769e9f5a..8e571998 100644 --- a/portal/django_passresetview.py +++ b/portal/django_passresetview.py @@ -34,7 +34,7 @@ If the email address provided does not exist in the system, this view won't send This prevents information leaking to potential attackers. If you want to provide an error message in this case, you can subclass PasswordResetForm and use the password_reset_form argument. -Users flagged with an unusable password (see set_unusable_password() aren't allowed to request a password reset to prevent misuse when using an external +Users flagged with an unusable password - see set_unusable_password() - aren't allowed to request a password reset to prevent misuse when using an external authentication source like LDAP. Note that they won't receive any error message since this would expose their account's existence but no mail will be sent either. More Detail: https://docs.djangoproject.com/en/dev/topics/auth/default/#topics-auth-creating-users @@ -64,7 +64,7 @@ from django.contrib.auth.decorators import login_required from portal.forms import PasswordResetForm, SetPasswordForm from django.contrib.auth.tokens import default_token_generator from django.contrib.sites.models import get_current_site -from django.contrib.auth.hashers import UNUSABLE_PASSWORD, identify_hasher +from django.contrib.auth.hashers import identify_hasher ## import os.path, re diff --git a/portal/forms.py b/portal/forms.py index afbf3442..61ffb860 100644 --- a/portal/forms.py +++ b/portal/forms.py @@ -28,15 +28,26 @@ from portal.models import PendingUser, PendingSlice from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.tokens import default_token_generator from django.contrib.auth import authenticate, get_user_model -# TODO: Remove these automated forms and use html templates and views like any other page ! -# ERROR ImportError: cannot import name UNUSABLE_PASSWORD -# XXX This is not compatible with Django 1.6.1 -# Ref: https://github.com/dot2code/varnish-bans-manager/issues/8 -from django.contrib.auth.hashers import UNUSABLE_PASSWORD, identify_hasher from django.contrib.sites.models import get_current_site from django.utils.http import int_to_base36 from django.template import loader +# TODO: Remove these automated forms and use html templates and views like any other page ! +from django.contrib.auth.hashers import identify_hasher +# adapted from https://sourcegraph.com/github.com/fusionbox/django-authtools/symbols/python/authtools/forms + +def is_password_unusable(pw): + # like Django's is_password_usable, but only checks for unusable + # passwords, not invalidly encoded passwords too. + try: + # 1.5 + from django.contrib.auth.hashers import UNUSABLE_PASSWORD + return pw == UNUSABLE_PASSWORD + except ImportError: + # 1.6 + from django.contrib.auth.hashers import UNUSABLE_PASSWORD_PREFIX + return pw.startswith(UNUSABLE_PASSWORD_PREFIX) + @@ -146,8 +157,7 @@ class PasswordResetForm(forms.Form): if not any(user.is_active for user in self.users_cache): # none of the filtered users are active raise forms.ValidationError(self.error_messages['unknown']) - if any((user.password == UNUSABLE_PASSWORD) - for user in self.users_cache): + if any(is_password_unusable(user.password) for user in self.users_cache): raise forms.ValidationError(self.error_messages['unusable']) return email -- 2.43.0