Files
horizon/openstack_dashboard/dashboards/settings/password/forms.py
Akihiro Motoki 6a07f5a5b4 Avoid stripping leading/traling spaces in password forms
There are cases where leading/trailing spaces are included in passwords
We should not touch passwords input in forms and pass them to auth
backends without any modifications. The detail was discussed in
the mailing list thread [1] referred in the bug comment.

[1] http://lists.openstack.org/pipermail/openstack-discuss/2020-January/thread.html#12223

Change-Id: I98de224cc77a98fa216ec3bc032412325e661e14
Closes-Bug: #1861224
2020-02-05 14:41:49 +09:00

82 lines
3.3 KiB
Python

# Copyright 2013 Centrin Data Systems Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from django.conf import settings
from django.forms import ValidationError
from django import http
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.debug import sensitive_variables
from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon.utils import functions as utils
from horizon.utils import validators
from openstack_dashboard import api
class PasswordForm(forms.SelfHandlingForm):
current_password = forms.CharField(
label=_("Current password"),
strip=False,
widget=forms.PasswordInput(render_value=False))
new_password = forms.RegexField(
label=_("New password"),
strip=False,
widget=forms.PasswordInput(render_value=False),
regex=validators.password_validator(),
error_messages={'invalid':
validators.password_validator_msg()})
confirm_password = forms.CharField(
label=_("Confirm new password"),
strip=False,
widget=forms.PasswordInput(render_value=False))
no_autocomplete = True
def clean(self):
'''Check to make sure password fields match.'''
data = super(PasswordForm, self).clean()
if 'new_password' in data:
if data['new_password'] != data.get('confirm_password', None):
raise ValidationError(_('Passwords do not match.'))
if data.get('confirm_password', None) == \
data.get('current_password', None):
raise ValidationError(_('Old password and new password '
'must be different'))
return data
# We have to protect the entire "data" dict because it contains the
# oldpassword and newpassword strings.
@sensitive_variables('data')
def handle(self, request, data):
user_is_editable = api.keystone.keystone_can_edit_user()
if user_is_editable:
try:
api.keystone.user_update_own_password(request,
data['current_password'],
data['new_password'])
response = http.HttpResponseRedirect(settings.LOGOUT_URL)
msg = _("Password changed. Please log in again to continue.")
utils.add_logout_reason(request, response, msg)
return response
except Exception as ex:
exceptions.handle(request,
_('Unable to change password: %s') % ex)
return False
else:
messages.error(request, _('Changing password is not supported.'))
return False