Browse Source

Merge "Display a message on the login page"

Jenkins 5 years ago
parent
commit
a67b298c33

+ 9
- 4
horizon/middleware.py View File

@@ -34,9 +34,10 @@ from django.http import HttpResponseRedirect  # noqa
34 34
 from django import shortcuts
35 35
 from django.utils.encoding import iri_to_uri  # noqa
36 36
 from django.utils import timezone
37
+from django.utils.translation import ugettext_lazy as _  # noqa
37 38
 
38 39
 from horizon import exceptions
39
-
40
+from horizon.utils import functions as utils
40 41
 
41 42
 LOG = logging.getLogger(__name__)
42 43
 
@@ -62,7 +63,10 @@ class HorizonMiddleware(object):
62 63
         timestamp = datetime.datetime.now()
63 64
         if last_activity and (timestamp - last_activity).seconds > timeout:
64 65
             request.session.pop('last_activity')
65
-            return HttpResponseRedirect(settings.LOGOUT_URL)
66
+            response = HttpResponseRedirect(settings.LOGOUT_URL)
67
+            reason = _("Session timed out.")
68
+            utils.add_logout_reason(request, response, reason)
69
+            return response
66 70
         request.session['last_activity'] = timestamp
67 71
 
68 72
         request.horizon = {'dashboard': None,
@@ -86,12 +90,13 @@ class HorizonMiddleware(object):
86 90
             response = redirect_to_login(next_url, login_url=login_url,
87 91
                                          redirect_field_name=field_name)
88 92
 
89
-            # TODO(gabriel): Find a way to display an appropriate message to
90
-            # the user *on* the login form...
91 93
             if request.is_ajax():
92 94
                 response_401 = http.HttpResponse(status=401)
93 95
                 response_401['X-Horizon-Location'] = response['location']
94 96
                 return response_401
97
+            else:
98
+                utils.add_logout_reason(request, response, _("Unauthorized."))
99
+
95 100
             return response
96 101
 
97 102
         # If an internal "NotFound" error gets this far, return a real 404.

+ 5
- 0
horizon/templates/auth/_login.html View File

@@ -18,6 +18,11 @@
18 18
         <a href="{% url 'horizon:user_home' %}">{% trans "home page" %}</a></p>
19 19
       </span>
20 20
     </div>
21
+    {% endif  %}
22
+    {% if request.COOKIES.logout_reason %}
23
+    <div class="control-group clearfix error">
24
+      <span class="help-inline"><p>{{ request.COOKIES.logout_reason }}</p></span>
25
+    </div>
21 26
     {% endif %}
22 27
     {% if next %}<input type="hidden" name="{{ redirect_field_name }}" value="{{ next }}" />{% endif %}
23 28
     {% include "horizon/common/_form_fields.html" %}

+ 2
- 2
horizon/test/helpers.py View File

@@ -60,14 +60,14 @@ class RequestFactoryWithMessages(RequestFactory):
60 60
     def get(self, *args, **kwargs):
61 61
         req = super(RequestFactoryWithMessages, self).get(*args, **kwargs)
62 62
         req.user = User()
63
-        req.session = []
63
+        req.session = {}
64 64
         req._messages = default_storage(req)
65 65
         return req
66 66
 
67 67
     def post(self, *args, **kwargs):
68 68
         req = super(RequestFactoryWithMessages, self).post(*args, **kwargs)
69 69
         req.user = User()
70
-        req.session = []
70
+        req.session = {}
71 71
         req._messages = default_storage(req)
72 72
         return req
73 73
 

+ 9
- 0
horizon/utils/functions.py View File

@@ -2,6 +2,7 @@ import math
2 2
 
3 3
 from django.utils.encoding import force_unicode  # noqa
4 4
 from django.utils.functional import lazy  # noqa
5
+from django.utils import translation
5 6
 
6 7
 
7 8
 def _lazy_join(separator, strings):
@@ -15,3 +16,11 @@ def bytes_to_gigabytes(bytes):
15 16
     # Converts the number of bytes to the next highest number of Gigabytes
16 17
     # For example 5000000 (5 Meg) would return '1'
17 18
     return int(math.ceil(float(bytes) / 1024 ** 3))
19
+
20
+
21
+def add_logout_reason(request, response, reason):
22
+    # Store the translated string in the cookie
23
+    lang = translation.get_language_from_request(request)
24
+    with translation.override(lang):
25
+        reason = unicode(reason).encode('utf-8')
26
+        response.set_cookie('logout_reason', reason, max_age=30)

+ 7
- 1
openstack_dashboard/dashboards/settings/password/forms.py View File

@@ -14,13 +14,16 @@
14 14
 #    License for the specific language governing permissions and limitations
15 15
 #    under the License.
16 16
 
17
+from django.conf import settings  # noqa
17 18
 from django.forms import ValidationError  # noqa
19
+from django import http
18 20
 from django.utils.translation import ugettext_lazy as _  # noqa
19 21
 from django.views.decorators.debug import sensitive_variables  # noqa
20 22
 
21 23
 from horizon import exceptions
22 24
 from horizon import forms
23 25
 from horizon import messages
26
+from horizon.utils import functions as utils
24 27
 from horizon.utils import validators
25 28
 
26 29
 from openstack_dashboard import api
@@ -56,7 +59,10 @@ class PasswordForm(forms.SelfHandlingForm):
56 59
                 api.keystone.user_update_own_password(request,
57 60
                                                     data['current_password'],
58 61
                                                     data['new_password'])
59
-                messages.success(request, _('Password changed.'))
62
+                response = http.HttpResponseRedirect(settings.LOGOUT_URL)
63
+                msg = _("Password changed. Please log in again to continue.")
64
+                utils.add_logout_reason(request, response, msg)
65
+                return response
60 66
             except Exception:
61 67
                 exceptions.handle(request,
62 68
                                   _('Unable to change password.'))

+ 18
- 6
openstack_dashboard/dashboards/settings/password/tests.py View File

@@ -31,27 +31,39 @@ class ChangePasswordTests(test.TestCase):
31 31
     @test.create_stubs({api.keystone: ('user_update_own_password', )})
32 32
     def test_change_password(self):
33 33
         api.keystone.user_update_own_password(IsA(http.HttpRequest),
34
-                                      'oldpwd',
35
-                                      'normalpwd',).AndReturn(None)
36
-
34
+                                              'oldpwd',
35
+                                              'normalpwd',).AndReturn(None)
37 36
         self.mox.ReplayAll()
38 37
 
39 38
         formData = {'method': 'PasswordForm',
40 39
                     'current_password': 'oldpwd',
41 40
                     'new_password': 'normalpwd',
42 41
                     'confirm_password': 'normalpwd'}
43
-
44 42
         res = self.client.post(INDEX_URL, formData)
45 43
 
46 44
         self.assertNoFormErrors(res)
47 45
 
48 46
     def test_change_validation_passwords_not_matching(self):
49
-
50 47
         formData = {'method': 'PasswordForm',
51 48
                     'current_password': 'currpasswd',
52 49
                     'new_password': 'testpassword',
53 50
                     'confirm_password': 'doesnotmatch'}
54
-
55 51
         res = self.client.post(INDEX_URL, formData)
56 52
 
57 53
         self.assertFormError(res, "form", None, ['Passwords do not match.'])
54
+
55
+    @test.create_stubs({api.keystone: ('user_update_own_password', )})
56
+    def test_change_password_shows_message_on_login_page(self):
57
+        api.keystone.user_update_own_password(IsA(http.HttpRequest),
58
+                                              'oldpwd',
59
+                                              'normalpwd').AndReturn(None)
60
+        self.mox.ReplayAll()
61
+
62
+        formData = {'method': 'PasswordForm',
63
+                    'current_password': 'oldpwd',
64
+                    'new_password': 'normalpwd',
65
+                    'confirm_password': 'normalpwd'}
66
+        res = self.client.post(INDEX_URL, formData, follow=True)
67
+
68
+        info_msg = "Password changed. Please log in again to continue."
69
+        self.assertContains(res, info_msg)

Loading…
Cancel
Save