From db1cc15f1fff411b152bd3550f3ca81579a35937 Mon Sep 17 00:00:00 2001 From: Henrik Levkowetz Date: Wed, 8 Feb 2017 18:03:29 +0000 Subject: [PATCH] Undid last commit - Legacy-Id: 12792 --- ietf/bower.json | 3 +- ietf/ietfauth/forms.py | 32 +---- ietf/ietfauth/urls.py | 27 ++-- ietf/ietfauth/views.py | 64 ++------- ietf/ipr/views.py | 3 - ietf/settings.py | 11 +- ietf/static/ietf/js/password_strength.js | 130 ------------------ ietf/templates/base/menu_user.html | 6 +- ietf/templates/ipr/details_view.html | 12 +- .../registration/change_password.html | 54 ++------ ietf/templates/registration/create.html | 30 ++-- ietf/templates/registration/edit_profile.html | 7 - ietf/templates/registration/login.html | 39 +++--- requirements.txt | 3 - 14 files changed, 80 insertions(+), 341 deletions(-) delete mode 100644 ietf/static/ietf/js/password_strength.js diff --git a/ietf/bower.json b/ietf/bower.json index 03d1ecb9b..710d76ec7 100644 --- a/ietf/bower.json +++ b/ietf/bower.json @@ -15,8 +15,7 @@ "respond": "~1", "select2": "~3", "select2-bootstrap-css": "~1", - "spin.js": "~2", - "zxcvbn": "~4" + "spin.js": "~2" }, "devDependencies": {}, "overrides": { diff --git a/ietf/ietfauth/forms.py b/ietf/ietfauth/forms.py index f30f8c103..08b0ee9d4 100644 --- a/ietf/ietfauth/forms.py +++ b/ietf/ietfauth/forms.py @@ -1,5 +1,4 @@ import re -from unidecode import unidecode from django import forms from django.conf import settings @@ -9,7 +8,7 @@ from django.contrib.auth.models import User from django.utils.html import mark_safe from django.core.urlresolvers import reverse as urlreverse -from django_password_strength.widgets import PasswordStrengthInput, PasswordConfirmationInput +from unidecode import unidecode import debug # pyflakes:ignore @@ -32,8 +31,8 @@ class RegistrationForm(forms.Form): class PasswordForm(forms.Form): - password = forms.CharField(widget=PasswordStrengthInput) - password_confirmation = forms.CharField(widget=PasswordConfirmationInput, + password = forms.CharField(widget=forms.PasswordInput) + password_confirmation = forms.CharField(widget=forms.PasswordInput, help_text="Enter the same password as above, for verification.") def clean_password_confirmation(self): @@ -167,28 +166,3 @@ class WhitelistForm(forms.ModelForm): exclude = ['by', 'time' ] -from django import forms - - -class ChangePasswordForm(forms.Form): - current_password = forms.CharField(widget=forms.PasswordInput) - - - new_password = forms.CharField(widget=PasswordStrengthInput) - new_password_confirmation = forms.CharField(widget=PasswordConfirmationInput) - - def __init__(self, user, data=None): - self.user = user - super(ChangePasswordForm, self).__init__(data) - - def clean_current_password(self): - password = self.cleaned_data.get('current_password', None) - if not self.user.check_password(password): - raise ValidationError('Invalid password') - - def clean(self): - new_password = self.cleaned_data.get('new_password', None) - conf_password = self.cleaned_data.get('new_password_confirmation', None) - if not new_password == conf_password: - raise ValidationError("The password confirmation is different than the new password") - diff --git a/ietf/ietfauth/urls.py b/ietf/ietfauth/urls.py index ee278a4d4..1bc247554 100644 --- a/ietf/ietfauth/urls.py +++ b/ietf/ietfauth/urls.py @@ -3,20 +3,23 @@ from django.conf.urls import url from django.contrib.auth.views import login, logout -from ietf.ietfauth import views +from ietf.ietfauth.views import add_account_whitelist urlpatterns = [ - url(r'^$', views.index), - url(r'^confirmnewemail/(?P[^/]+)/$', views.confirm_new_email), - url(r'^create/$', views.create_account), - url(r'^create/confirm/(?P[^/]+)/$', views.confirm_account), + url(r'^$', 'ietf.ietfauth.views.index'), +# url(r'^login/$', 'ietf.ietfauth.views.ietf_login'), url(r'^login/$', login), url(r'^logout/$', logout), - url(r'^password/$', views.change_password), - url(r'^profile/$', views.profile), - url(r'^reset/$', views.password_reset), - url(r'^reset/confirm/(?P[^/]+)/$', views.confirm_password_reset), - url(r'^review/$', views.review_overview), - url(r'^testemail/$', views.test_email), - url(r'whitelist/add/?$', views.add_account_whitelist), +# url(r'^loggedin/$', 'ietf.ietfauth.views.ietf_loggedin'), +# url(r'^loggedout/$', 'ietf.ietfauth.views.logged_out'), + url(r'^profile/$', 'ietf.ietfauth.views.profile'), +# (r'^login/(?P[a-z0-9.@]+)/(?P.+)$', 'ietf.ietfauth.views.url_login'), + url(r'^testemail/$', 'ietf.ietfauth.views.test_email'), + url(r'^create/$', 'ietf.ietfauth.views.create_account'), + url(r'^create/confirm/(?P[^/]+)/$', 'ietf.ietfauth.views.confirm_account'), + url(r'^reset/$', 'ietf.ietfauth.views.password_reset'), + url(r'^reset/confirm/(?P[^/]+)/$', 'ietf.ietfauth.views.confirm_password_reset'), + url(r'^confirmnewemail/(?P[^/]+)/$', 'ietf.ietfauth.views.confirm_new_email'), + url(r'whitelist/add/?$', add_account_whitelist), + url(r'^review/$', 'ietf.ietfauth.views.review_overview'), ] diff --git a/ietf/ietfauth/views.py b/ietf/ietfauth/views.py index 56bb4f4a1..8b3c18ff1 100644 --- a/ietf/ietfauth/views.py +++ b/ietf/ietfauth/views.py @@ -32,27 +32,24 @@ # Copyright The IETF Trust 2007, All Rights Reserved -import importlib - from datetime import datetime as DateTime, timedelta as TimeDelta, date as Date from collections import defaultdict -import django.core.signing -from django import forms -from django.contrib import messages from django.conf import settings -from django.contrib.auth import update_session_auth_hash -from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User -from django.contrib.sites.models import Site -from django.core.urlresolvers import reverse as urlreverse -from django.http import Http404, HttpResponseRedirect #, HttpResponse, +from django.http import Http404 #, HttpResponse, HttpResponseRedirect from django.shortcuts import render, redirect, get_object_or_404 +#from django.contrib.auth import REDIRECT_FIELD_NAME, authenticate, login +from django.contrib.auth.decorators import login_required +#from django.utils.http import urlquote +import django.core.signing +from django.contrib.sites.models import Site +from django.contrib.auth.models import User +from django import forms import debug # pyflakes:ignore from ietf.group.models import Role, Group -from ietf.ietfauth.forms import RegistrationForm, PasswordForm, ResetPasswordForm, TestEmailForm, WhitelistForm, ChangePasswordForm +from ietf.ietfauth.forms import RegistrationForm, PasswordForm, ResetPasswordForm, TestEmailForm, WhitelistForm from ietf.ietfauth.forms import get_person_form, RoleEmailForm, NewEmailForm from ietf.ietfauth.htpasswd import update_htpasswd_file from ietf.ietfauth.utils import role_required @@ -468,46 +465,3 @@ def review_overview(request): 'review_wishes': review_wishes, 'review_wish_form': review_wish_form, }) - -@login_required -def change_password(request): - success = False - person = None - - try: - person = request.user.person - except Person.DoesNotExist: - return render(request, 'registration/missing_person.html') - - emails = Email.objects.filter(person=person, active=True).order_by('-primary','-time').first - - if request.method == 'POST': - user = request.user - form = ChangePasswordForm(user, request.POST) - if form.is_valid(): - new_password = form.cleaned_data["new_password"] - - user.set_password(new_password) - user.save() - # password is also stored in htpasswd file - update_htpasswd_file(user.username, new_password) - # keep the session - update_session_auth_hash(request, user) - - messages.success(request, "Your password was successfully changed") - return HttpResponseRedirect(urlreverse('ietf.ietfauth.views.profile')) - - else: - form = ChangePasswordForm(request.user) - - hlibname, hashername = settings.PASSWORD_HASHERS[0].rsplit('.',1) - - hlib = importlib.import_module(hlibname) - hasher = getattr(hlib, hashername) - return render(request, 'registration/change_password.html', { - 'form': form, - 'success': success, - 'hasher': hasher, - }) - - diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py index cf59220de..3ec7a0a3d 100644 --- a/ietf/ipr/views.py +++ b/ietf/ipr/views.py @@ -32,7 +32,6 @@ from ietf.ipr.utils import (get_genitive, get_ipr_summary, iprs_from_docs, related_docs) from ietf.message.models import Message from ietf.message.utils import infer_message -from ietf.name.models import IprLicenseTypeName from ietf.person.models import Person from ietf.secr.utils.document import get_rfc_num, is_draft from ietf.utils.draft_search import normalize_draftname @@ -704,7 +703,6 @@ def get_details_tabs(ipr, selected): ('History', urlreverse('ipr_history', kwargs={ 'id': ipr.pk })) ]] -@debug.trace def show(request, id): """View of individual declaration""" ipr = get_object_or_404(IprDisclosureBase, id=id).get_child() @@ -719,7 +717,6 @@ def show(request, id): return render(request, "ipr/details_view.html", { 'ipr': ipr, 'tabs': get_details_tabs(ipr, 'Disclosure'), - 'choices_abc': [ i.desc for i in IprLicenseTypeName.objects.filter(slug__in=['no-license', 'royalty-free', 'reasonable', ]) ], 'updates_iprs': ipr.relatedipr_source_set.all(), 'updated_by_iprs': ipr.relatedipr_target_set.filter(source__state="posted") }) diff --git a/ietf/settings.py b/ietf/settings.py index 216f5b6bc..7171f3ca1 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -54,13 +54,6 @@ ADMINS = ( ('Ryan Cross', 'rcross@amsl.com'), ) -PASSWORD_HASHERS = [ - 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', - 'django.contrib.auth.hashers.PBKDF2PasswordHasher', - 'django.contrib.auth.hashers.SHA1PasswordHasher', - 'django.contrib.auth.hashers.CryptPasswordHasher', -] - ALLOWED_HOSTS = [".ietf.org", ".ietf.org.", "209.208.19.216", "4.31.198.44", ] @@ -303,12 +296,11 @@ INSTALLED_APPS = ( 'django.contrib.staticfiles', # External apps 'bootstrap3', - 'django_markup', - 'django_password_strength', 'djangobwr', 'form_utils', 'tastypie', 'widget_tweaks', + 'django_markup', # IETF apps 'ietf.api', 'ietf.community', @@ -790,6 +782,7 @@ SILENCED_SYSTEM_CHECKS = [ "fields.W342", # Setting unique=True on a ForeignKey has the same effect as using a OneToOneField. ] + # Put the production SECRET_KEY in settings_local.py, and also any other # sensitive or site-specific changes. DO NOT commit settings_local.py to svn. from settings_local import * # pyflakes:ignore pylint: disable=wildcard-import diff --git a/ietf/static/ietf/js/password_strength.js b/ietf/static/ietf/js/password_strength.js deleted file mode 100644 index a1fd393f5..000000000 --- a/ietf/static/ietf/js/password_strength.js +++ /dev/null @@ -1,130 +0,0 @@ -// Taken from django-password-strength, with changes to use the bower-managed zxcvbn.js The -// bower-managed zxcvbn.js is kept up-to-date to a larger extent than the copy packaged with -// the django-password-strength component. -(function($, window, document, undefined){ - window.djangoPasswordStrength = { - config: { - passwordClass: 'password_strength', - confirmationClass: 'password_confirmation' - }, - - init: function (config) { - var self = this; - // Setup configuration - if ($.isPlainObject(config)) { - $.extend(self.config, config); - } - - self.initListeners(); - }, - - initListeners: function() { - var self = this; - var body = $('body'); - - $('.' + self.config.passwordClass).on('keyup', function() { - var password_strength_bar = $(this).parent().find('.password_strength_bar'); - var password_strength_info = $(this).parent().find('.password_strength_info'); - - if( $(this).val() ) { - var result = zxcvbn( $(this).val() ); - - if( result.score < 3 ) { - password_strength_bar.removeClass('progress-bar-success').addClass('progress-bar-warning'); - password_strength_info.find('.label').removeClass('hidden'); - } else { - password_strength_bar.removeClass('progress-bar-warning').addClass('progress-bar-success'); - password_strength_info.find('.label').addClass('hidden'); - } - - password_strength_bar.width( ((result.score+1)/5)*100 + '%' ).attr('aria-valuenow', result.score + 1); - // henrik@levkowetz.com -- this is the only changed line: - password_strength_info.find('.password_strength_time').html(result.crack_times_display.online_no_throttling_10_per_second); - password_strength_info.removeClass('hidden'); - } else { - password_strength_bar.removeClass('progress-bar-success').addClass('progress-bar-warning'); - password_strength_bar.width( '0%' ).attr('aria-valuenow', 0); - password_strength_info.addClass('hidden'); - } - self.match_passwords($(this)); - }); - - var timer = null; - $('.' + self.config.confirmationClass).on('keyup', function() { - var password_field; - var confirm_with = $(this).data('confirm-with'); - - if( confirm_with ) { - password_field = $('#' + confirm_with); - } else { - password_field = $('.' + self.config.passwordClass); - } - - if (timer !== null) clearTimeout(timer); - - timer = setTimeout(function(){ - self.match_passwords(password_field); - }, 400); - }); - }, - - display_time: function(seconds) { - var minute = 60; - var hour = minute * 60; - var day = hour * 24; - var month = day * 31; - var year = month * 12; - var century = year * 100; - - // Provide fake gettext for when it is not available - if( typeof gettext !== 'function' ) { gettext = function(text) { return text; }; }; - - if( seconds < minute ) return gettext('only an instant'); - if( seconds < hour) return (1 + Math.ceil(seconds / minute)) + ' ' + gettext('minutes'); - if( seconds < day) return (1 + Math.ceil(seconds / hour)) + ' ' + gettext('hours'); - if( seconds < month) return (1 + Math.ceil(seconds / day)) + ' ' + gettext('days'); - if( seconds < year) return (1 + Math.ceil(seconds / month)) + ' ' + gettext('months'); - if( seconds < century) return (1 + Math.ceil(seconds / year)) + ' ' + gettext('years'); - - return gettext('centuries'); - }, - - match_passwords: function(password_field, confirmation_fields) { - var self = this; - // Optional parameter: if no specific confirmation field is given, check all - if( confirmation_fields === undefined ) { confirmation_fields = $('.' + self.config.confirmationClass) } - if( confirmation_fields === undefined ) { return; } - - var password = password_field.val(); - - confirmation_fields.each(function(index, confirm_field) { - var confirm_value = $(confirm_field).val(); - var confirm_with = $(confirm_field).data('confirm-with'); - - if( confirm_with && confirm_with == password_field.attr('id')) { - if( confirm_value && password ) { - if (confirm_value === password) { - $(confirm_field).parent().find('.password_strength_info').addClass('hidden'); - } else { - $(confirm_field).parent().find('.password_strength_info').removeClass('hidden'); - } - } else { - $(confirm_field).parent().find('.password_strength_info').addClass('hidden'); - } - } - }); - - // If a password field other than our own has been used, add the listener here - if( !password_field.hasClass(self.config.passwordClass) && !password_field.data('password-listener') ) { - password_field.on('keyup', function() { - self.match_passwords($(this)); - }); - password_field.data('password-listener', true); - } - } - }; - - // Call the init for backwards compatibility - djangoPasswordStrength.init(); - -})(jQuery, window, document); diff --git a/ietf/templates/base/menu_user.html b/ietf/templates/base/menu_user.html index 697a145b8..79f1a72c5 100644 --- a/ietf/templates/base/menu_user.html +++ b/ietf/templates/base/menu_user.html @@ -16,16 +16,14 @@ {% else %} {% if user.is_authenticated %}
  • Sign out
  • -
  • Account info
  • +
  • Edit profile
  • {% else %}
  • Sign in
  • Password reset
  • {% endif %} {% endif %} - {% if not request.user.is_authenticated %} -
  • New account
  • - {% endif %} +
  • {% if request.user.is_authenticated %}Manage account{% else %}New account{% endif %}
  • Preferences
  • {% if user|has_role:"Reviewer" %} diff --git a/ietf/templates/ipr/details_view.html b/ietf/templates/ipr/details_view.html index 3dca63f7f..bbac6ef63 100644 --- a/ietf/templates/ipr/details_view.html +++ b/ietf/templates/ipr/details_view.html @@ -200,19 +200,9 @@ specification, is as follows(select one licensing declaration option only):

    - {% if ipr.licensing.slug == "provided-later" %} -
    - Possible licencing choices a), b), and c) when Licencing Declaration to be Provided Later: -
      - {% for desc in choices_abc %} -
    • {{ desc}}
    • - {% endfor %} -
    -

    - {% endif %}
    Licensing
    -
    {% if ipr.licensing.slug == "provided-later" %}{{ ipr.licensing.desc|slice:"2:"|slice:":117" }}){% else %}{{ ipr.licensing.desc|slice:"2:" }}{% endif %}
    +
    {% if ipr.licensing.slug == "later" %}{{ ipr.licensing.desc|slice:"2:"|slice:":43" }}{% else %}{{ ipr.licensing.desc|slice:"2:" }}{% endif %}
    Licensing information, comments, notes, or URL for further information
    {{ ipr.licensing_comments|default:"(No information submitted)"|linebreaks }}
    diff --git a/ietf/templates/registration/change_password.html b/ietf/templates/registration/change_password.html index 34518b917..26321558a 100644 --- a/ietf/templates/registration/change_password.html +++ b/ietf/templates/registration/change_password.html @@ -3,56 +3,30 @@ {% load origin %} {% load bootstrap3 %} -{% load staticfiles %} -{% block title %}Account creation{% endblock %} - -{% block js %} - {{ block.super }} - - -{% endblock %} +{% block title %}Change password{% endblock %} {% block content %} {% origin %} {% if success %} -

    Your password was successfully changed.

    +

    Password change successful

    + +

    Your password has been updated.

    + Sign in {% else %} -
    -
    -
    -

    Change password

    +

    Change password

    -
    - {% csrf_token %} - {% bootstrap_form form %} +

    You can change the password below for your user {{ username }} below.

    + + {% csrf_token %} + {% bootstrap_form form %} - {% buttons %} - - {% endbuttons %} -
    - -
    - This password change form uses the - zxcvbn - password strength estimator to give an indication of password strength. - The crack times given assume online attack without rate limiting, - at a rate of 10 attempts per second. -
    - -
    - The datatracker currently uses a {{ hasher.algorithm }}-based - password hasher with - {% if hasher.iterations %}{{ hasher.iterations }} iterations{% else %}{{ hasher.rounds }} rounds{% endif %}. - Calculating offline attack time if password hashes wouldleak is left - as an excercise for the reader. -
    - -
    -
    -
    + {% buttons %} + + {% endbuttons %} + {% endif %} {% endblock %} diff --git a/ietf/templates/registration/create.html b/ietf/templates/registration/create.html index 7bb32242c..2c12c9a1e 100644 --- a/ietf/templates/registration/create.html +++ b/ietf/templates/registration/create.html @@ -18,9 +18,22 @@ {% else %}
    -
    -
    +

    Account creation

    +

    Please enter your email address in order to create a new datatracker account.

    +
    + {% csrf_token %} + {% bootstrap_form form %} + + {% buttons %} + + {% endbuttons %} +
    +
    + +
    +

    Other options

    +

    If you already have an account and want to use a new email address, please go to your account profile page and @@ -36,20 +49,7 @@

    Reset your password

    - -
    - -

    Please enter your email address in order to create your datatracker account.

    -
    - {% csrf_token %} - {% bootstrap_form form %} - - {% buttons %} - - {% endbuttons %} -
    -
    {% endif %} {% endblock %} diff --git a/ietf/templates/registration/edit_profile.html b/ietf/templates/registration/edit_profile.html index 44c89d04f..9c4bccad5 100644 --- a/ietf/templates/registration/edit_profile.html +++ b/ietf/templates/registration/edit_profile.html @@ -22,13 +22,6 @@
    -
    - - -
    -
    diff --git a/ietf/templates/registration/login.html b/ietf/templates/registration/login.html index 732426cad..e64d9423e 100644 --- a/ietf/templates/registration/login.html +++ b/ietf/templates/registration/login.html @@ -8,27 +8,24 @@ {% block content %} {% origin %} -
    -
    -

    Sign in

    +

    Sign in

    -
    - {% csrf_token %} - {% bootstrap_form form %} + + {% csrf_token %} + {% bootstrap_form form %} + + {% buttons %} + + + + + +
    + + + Forgot your password? Request a reset. +
    + {% endbuttons %} +
    - {% buttons %} - - - - - -
    - - - Forgot your password? Request a reset. -
    - {% endbuttons %} - -
    -
    {% endblock %} diff --git a/requirements.txt b/requirements.txt index 2061988d1..8442eaa03 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,11 +8,9 @@ coverage>=4.0.1,!=4.0.2 decorator>=3.4.0 defusedxml>=0.4.1 # for TastyPie when ussing xml; not a declared dependency Django>=1.9,<1.10 -django-bcrypt>=0.9.2 django-bootstrap3>=7.0 django-formtools>=1.0 # instead of django.contrib.formtools in 1.8 django-markup>=1.1 -django-password-strength>=1.2.1 django-tastypie>=0.13.1 django-widget-tweaks>=1.3 docutils>=0.12 @@ -45,4 +43,3 @@ Unidecode>=0.4.18 #wsgiref>=0.1.2 xml2rfc>=2.5. xym>=0.1.2,!=0.3 -zxcvbn-python>=4.4.14