Logging user out after self password change

Admin users where not logged out after changing their own password in the user
settings pannel, and error messages where displayed afterwards.

Fixes bug 1226829

Change-Id: Iec0e34484e2bbc28a300d6259aab1a682e4a00ff
(cherry-picked from commit 0aab590)
This commit is contained in:
Yves-Gwenael Bourhis 2013-10-08 18:53:25 +02:00 committed by Matthias Runge
parent 9465e54f7e
commit 0fa0fd0066
5 changed files with 52 additions and 8 deletions

View File

@ -122,11 +122,22 @@ class HorizonMiddleware(object):
getattr(django_messages, tag)(request, message, extra_tags) getattr(django_messages, tag)(request, message, extra_tags)
if response['location'].startswith(settings.LOGOUT_URL): if response['location'].startswith(settings.LOGOUT_URL):
redirect_response = http.HttpResponse(status=401) redirect_response = http.HttpResponse(status=401)
# This header is used for handling the logout in JS
redirect_response['logout'] = True
if self.logout_reason is not None: if self.logout_reason is not None:
utils.add_logout_reason( utils.add_logout_reason(
request, redirect_response, self.logout_reason) request, redirect_response, self.logout_reason)
else: else:
redirect_response = http.HttpResponse() redirect_response = http.HttpResponse()
# Copy cookies from HttpResponseRedirect towards HttpResponse
for cookie_name, cookie in response.cookies.iteritems():
cookie_kwargs = dict((
(key, value) for key, value in cookie.iteritems()
if key in ('max_age', 'expires', 'path', 'domain',
'secure', 'httponly') and value
))
redirect_response.set_cookie(
cookie_name, cookie.value, **cookie_kwargs)
redirect_response['X-Horizon-Location'] = response['location'] redirect_response['X-Horizon-Location'] = response['location']
return redirect_response return redirect_response
if queued_msgs: if queued_msgs:

View File

@ -121,9 +121,13 @@ horizon.addInitFunction(function() {
} }
}, },
error: function (jqXHR, status, errorThrown) { error: function (jqXHR, status, errorThrown) {
if (jqXHR.getResponseHeader('logout')) {
location.href = jqXHR.getResponseHeader("X-Horizon-Location");
} else {
$form.closest(".modal").modal("hide"); $form.closest(".modal").modal("hide");
horizon.alert("error", gettext("There was an error submitting the form. Please try again.")); horizon.alert("error", gettext("There was an error submitting the form. Please try again."));
} }
}
}); });
}); });

View File

@ -1,5 +1,8 @@
import math import math
from django.conf import settings # noqa
from django.contrib.auth import logout # noqa
from django import http
from django.utils.encoding import force_unicode # noqa from django.utils.encoding import force_unicode # noqa
from django.utils.functional import lazy # noqa from django.utils.functional import lazy # noqa
from django.utils import translation from django.utils import translation
@ -24,3 +27,16 @@ def add_logout_reason(request, response, reason):
with translation.override(lang): with translation.override(lang):
reason = unicode(reason).encode('utf-8') reason = unicode(reason).encode('utf-8')
response.set_cookie('logout_reason', reason, max_age=30) response.set_cookie('logout_reason', reason, max_age=30)
def logout_with_message(request, msg):
"""Send HttpResponseRedirect to LOGOUT_URL.
`msg` is a message displayed on the login page after the logout, to explain
the logout reson.
"""
logout(request)
response = http.HttpResponseRedirect(
'%s?next=%s' % (settings.LOGOUT_URL, request.path))
add_logout_reason(request, response, msg)
return response

View File

@ -23,7 +23,6 @@ import logging
import urlparse import urlparse
from django.conf import settings # noqa from django.conf import settings # noqa
from django.contrib.auth import logout # noqa
from django.utils.translation import ugettext_lazy as _ # noqa from django.utils.translation import ugettext_lazy as _ # noqa
from keystoneclient import exceptions as keystone_exceptions from keystoneclient import exceptions as keystone_exceptions
@ -32,6 +31,7 @@ from openstack_auth import backend
from horizon import exceptions from horizon import exceptions
from horizon import messages from horizon import messages
from horizon.utils import functions as utils
from openstack_dashboard.api import base from openstack_dashboard.api import base
@ -354,8 +354,11 @@ def user_update(request, user, **data):
if password: if password:
try: try:
user_update_password(request, user, password) user_update_password(request, user, password)
if user == request.user.id: if user.id == request.user.id:
logout(request) return utils.logout_with_message(
request,
_("Password changed. Please log in again to continue.")
)
except Exception: except Exception:
error = exceptions.handle(request, ignore=True) error = exceptions.handle(request, ignore=True)
@ -367,6 +370,11 @@ def user_update(request, user, **data):
if not data['password']: if not data['password']:
data.pop('password') data.pop('password')
user = manager.update(user, **data) user = manager.update(user, **data)
if data.get('password') and user.id == request.user.id:
return utils.logout_with_message(
request,
_("Password changed. Please log in again to continue.")
)
return VERSIONS.upgrade_v2_user(user) return VERSIONS.upgrade_v2_user(user)

View File

@ -21,6 +21,7 @@
import logging import logging
from django.forms import ValidationError # noqa from django.forms import ValidationError # noqa
from django import http
from django.utils.translation import ugettext_lazy as _ # noqa from django.utils.translation import ugettext_lazy as _ # noqa
from django.views.decorators.debug import sensitive_variables # noqa from django.views.decorators.debug import sensitive_variables # noqa
@ -185,10 +186,14 @@ class UpdateUserForm(BaseUserForm):
data.pop('domain_name') data.pop('domain_name')
try: try:
api.keystone.user_update(request, user, **data) response = api.keystone.user_update(request, user, **data)
messages.success(request, messages.success(request,
_('User has been updated successfully.')) _('User has been updated successfully.'))
except Exception: except Exception:
exceptions.handle(request, ignore=True) response = exceptions.handle(request, ignore=True)
messages.error(request, _('Unable to update the user.')) messages.error(request, _('Unable to update the user.'))
if isinstance(response, http.HttpResponse):
return response
else:
return True return True