Browse Source

Merge "Logout user if he has no valid tokens" into stable/kilo

Jenkins 2 years ago
parent
commit
ced6c32e0a

+ 5
- 2
horizon/exceptions.py View File

@@ -203,6 +203,7 @@ class HandledException(HorizonException):
203 203
 
204 204
 
205 205
 UNAUTHORIZED = tuple(HORIZON_CONFIG['exceptions']['unauthorized'])
206
+UNAUTHORIZED += (NotAuthorized,)
206 207
 NOT_FOUND = tuple(HORIZON_CONFIG['exceptions']['not_found'])
207 208
 RECOVERABLE = (AlreadyExists, Conflict, NotAvailable, ServiceCatalogException)
208 209
 RECOVERABLE += tuple(HORIZON_CONFIG['exceptions']['recoverable'])
@@ -281,7 +282,8 @@ def handle_recoverable(request, message, redirect, ignore, escalate, handled,
281 282
 
282 283
 
283 284
 HANDLE_EXC_METHODS = [
284
-    {'exc': UNAUTHORIZED, 'handler': handle_unauthorized, 'set_wrap': False},
285
+    {'exc': UNAUTHORIZED, 'handler': handle_unauthorized,
286
+     'set_wrap': False, 'escalate': True},
285 287
     {'exc': NOT_FOUND, 'handler': handle_notfound, 'set_wrap': True},
286 288
     {'exc': RECOVERABLE, 'handler': handle_recoverable, 'set_wrap': True},
287 289
 ]
@@ -351,7 +353,8 @@ def handle(request, message=None, redirect=None, ignore=False,
351 353
             if exc_handler['set_wrap']:
352 354
                 wrap = True
353 355
             handler = exc_handler['handler']
354
-            ret = handler(request, message, redirect, ignore, escalate,
356
+            ret = handler(request, message, redirect, ignore,
357
+                          exc_handler.get('escalate', escalate),
355 358
                           handled, force_silence, force_log,
356 359
                           log_method, log_entry, log_level)
357 360
             if ret:

+ 6
- 0
horizon/middleware.py View File

@@ -158,6 +158,12 @@ class HorizonMiddleware(object):
158 158
             login_url = request.build_absolute_uri(auth_url)
159 159
             response = redirect_to_login(next_url, login_url=login_url,
160 160
                                          redirect_field_name=field_name)
161
+            if isinstance(exception, exceptions.NotAuthorized):
162
+                logout_reason = _("Unauthorized. Please try logging in again.")
163
+                utils.add_logout_reason(request, response, logout_reason)
164
+                # delete messages, created in get_data() method
165
+                # since we are going to redirect user to the login page
166
+                response.delete_cookie('messages')
161 167
 
162 168
             if request.is_ajax():
163 169
                 response_401 = http.HttpResponse(status=401)

+ 12
- 1
openstack_dashboard/dashboards/project/instances/tests.py View File

@@ -17,9 +17,11 @@
17 17
 #    under the License.
18 18
 
19 19
 import json
20
+import logging
20 21
 import sys
21 22
 
22 23
 from django.conf import settings
24
+from django.contrib.auth import REDIRECT_FIELD_NAME  # noqa
23 25
 from django.core.urlresolvers import reverse
24 26
 from django.forms import widgets
25 27
 from django import http
@@ -886,9 +888,18 @@ class InstanceTests(helpers.TestCase):
886 888
 
887 889
         url = reverse('horizon:project:instances:detail',
888 890
                       args=[server.id])
891
+
892
+        # Avoid the log message in the test
893
+        # when unauthorized exception will be logged
894
+        logging.disable(logging.ERROR)
889 895
         res = self.client.get(url)
896
+        logging.disable(logging.NOTSET)
890 897
 
891
-        self.assertRedirectsNoFollow(res, INDEX_URL)
898
+        self.assertEqual(302, res.status_code)
899
+        self.assertEqual(('Location', settings.TESTSERVER +
900
+                          settings.LOGIN_URL + '?' +
901
+                          REDIRECT_FIELD_NAME + '=' + url),
902
+                         res._headers.get('location', None),)
892 903
 
893 904
     def test_instance_details_flavor_not_found(self):
894 905
         server = self.servers.first()

+ 42
- 20
openstack_dashboard/dashboards/project/overview/tests.py View File

@@ -17,7 +17,10 @@
17 17
 #    under the License.
18 18
 
19 19
 import datetime
20
+import logging
20 21
 
22
+from django.conf import settings
23
+from django.contrib.auth import REDIRECT_FIELD_NAME  # noqa
21 24
 from django.core.urlresolvers import reverse
22 25
 from django import http
23 26
 from django.utils import timezone
@@ -34,7 +37,8 @@ INDEX_URL = reverse('horizon:project:overview:index')
34 37
 
35 38
 class UsageViewTests(test.TestCase):
36 39
 
37
-    def _stub_nova_api_calls(self, nova_stu_enabled=True):
40
+    def _stub_nova_api_calls(self, nova_stu_enabled=True,
41
+                             stu_exception=False):
38 42
         self.mox.StubOutWithMock(api.nova, 'usage_get')
39 43
         self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
40 44
         self.mox.StubOutWithMock(api.nova, 'extension_supported')
@@ -42,6 +46,9 @@ class UsageViewTests(test.TestCase):
42 46
             'SimpleTenantUsage', IsA(http.HttpRequest)) \
43 47
             .AndReturn(nova_stu_enabled)
44 48
 
49
+        if nova_stu_enabled and stu_exception:
50
+            self._nova_stu_enabled(stu_exception)
51
+
45 52
     def _stub_cinder_api_calls(self):
46 53
         self.mox.StubOutWithMock(api.cinder, 'tenant_absolute_limits')
47 54
         api.cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \
@@ -64,6 +71,20 @@ class UsageViewTests(test.TestCase):
64 71
             api.network.security_group_list(IsA(http.HttpRequest)) \
65 72
                 .AndReturn(self.q_secgroups.list())
66 73
 
74
+    def _nova_stu_enabled(self, exception=False):
75
+        now = timezone.now()
76
+        start = datetime.datetime(now.year, now.month, 1, 0, 0, 0, 0)
77
+        end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)
78
+
79
+        if exception:
80
+            api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
81
+                               start, end) \
82
+                .AndRaise(exception)
83
+        else:
84
+            api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
85
+                               start, end) \
86
+                .AndReturn(api.nova.NovaUsage(self.usages.first()))
87
+
67 88
     def test_usage(self):
68 89
         self._test_usage(nova_stu_enabled=True)
69 90
 
@@ -150,32 +171,33 @@ class UsageViewTests(test.TestCase):
150 171
             self.assertNotContains(res, 'form-inline')
151 172
         self.assertEqual(usages.limits['maxTotalFloatingIps'], 10)
152 173
 
153
-    def test_unauthorized(self):
154
-        exc = self.exceptions.nova_unauthorized
155
-        now = timezone.now()
156
-        self._stub_nova_api_calls()
174
+    @test.create_stubs({api.nova: ('usage_get',
175
+                                   'extension_supported')})
176
+    def _stub_nova_api_calls_unauthorized(self, exception):
157 177
         api.nova.extension_supported(
158 178
             'SimpleTenantUsage', IsA(http.HttpRequest)) \
159 179
             .AndReturn(True)
160
-        api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
161
-                           datetime.datetime(now.year,
162
-                                             now.month,
163
-                                             1, 0, 0, 0, 0),
164
-                           datetime.datetime(now.year,
165
-                                             now.month,
166
-                                             now.day, 23, 59, 59, 0)) \
167
-            .AndRaise(exc)
168
-        api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
169
-            .AndReturn(self.limits['absolute'])
170
-        self._stub_neutron_api_calls()
171
-        self._stub_cinder_api_calls()
180
+        self._nova_stu_enabled(exception)
181
+
182
+    def test_unauthorized(self):
183
+        self._stub_nova_api_calls_unauthorized(
184
+            self.exceptions.nova_unauthorized)
172 185
         self.mox.ReplayAll()
173 186
 
174 187
         url = reverse('horizon:project:overview:index')
188
+
189
+        # Avoid the log message in the test
190
+        # when unauthorized exception will be logged
191
+        logging.disable(logging.ERROR)
175 192
         res = self.client.get(url)
176
-        self.assertTemplateUsed(res, 'project/overview/usage.html')
177
-        self.assertMessageCount(res, error=1)
178
-        self.assertContains(res, 'Unauthorized:')
193
+        logging.disable(logging.NOTSET)
194
+
195
+        self.assertEqual(302, res.status_code)
196
+        self.assertEqual((
197
+            'Location', settings.TESTSERVER +
198
+            settings.LOGIN_URL + '?' +
199
+            REDIRECT_FIELD_NAME + '=' + url),
200
+            res._headers.get('location', None),)
179 201
 
180 202
     def test_usage_csv(self):
181 203
         self._test_usage_csv(nova_stu_enabled=True)

Loading…
Cancel
Save