Merge "Logout user if he has no valid tokens" into stable/kilo
This commit is contained in:
commit
ced6c32e0a
|
@ -203,6 +203,7 @@ class HandledException(HorizonException):
|
||||||
|
|
||||||
|
|
||||||
UNAUTHORIZED = tuple(HORIZON_CONFIG['exceptions']['unauthorized'])
|
UNAUTHORIZED = tuple(HORIZON_CONFIG['exceptions']['unauthorized'])
|
||||||
|
UNAUTHORIZED += (NotAuthorized,)
|
||||||
NOT_FOUND = tuple(HORIZON_CONFIG['exceptions']['not_found'])
|
NOT_FOUND = tuple(HORIZON_CONFIG['exceptions']['not_found'])
|
||||||
RECOVERABLE = (AlreadyExists, Conflict, NotAvailable, ServiceCatalogException)
|
RECOVERABLE = (AlreadyExists, Conflict, NotAvailable, ServiceCatalogException)
|
||||||
RECOVERABLE += tuple(HORIZON_CONFIG['exceptions']['recoverable'])
|
RECOVERABLE += tuple(HORIZON_CONFIG['exceptions']['recoverable'])
|
||||||
|
@ -281,7 +282,8 @@ def handle_recoverable(request, message, redirect, ignore, escalate, handled,
|
||||||
|
|
||||||
|
|
||||||
HANDLE_EXC_METHODS = [
|
HANDLE_EXC_METHODS = [
|
||||||
{'exc': UNAUTHORIZED, 'handler': handle_unauthorized, 'set_wrap': False},
|
{'exc': UNAUTHORIZED, 'handler': handle_unauthorized,
|
||||||
|
'set_wrap': False, 'escalate': True},
|
||||||
{'exc': NOT_FOUND, 'handler': handle_notfound, 'set_wrap': True},
|
{'exc': NOT_FOUND, 'handler': handle_notfound, 'set_wrap': True},
|
||||||
{'exc': RECOVERABLE, 'handler': handle_recoverable, 'set_wrap': True},
|
{'exc': RECOVERABLE, 'handler': handle_recoverable, 'set_wrap': True},
|
||||||
]
|
]
|
||||||
|
@ -351,7 +353,8 @@ def handle(request, message=None, redirect=None, ignore=False,
|
||||||
if exc_handler['set_wrap']:
|
if exc_handler['set_wrap']:
|
||||||
wrap = True
|
wrap = True
|
||||||
handler = exc_handler['handler']
|
handler = exc_handler['handler']
|
||||||
ret = handler(request, message, redirect, ignore, escalate,
|
ret = handler(request, message, redirect, ignore,
|
||||||
|
exc_handler.get('escalate', escalate),
|
||||||
handled, force_silence, force_log,
|
handled, force_silence, force_log,
|
||||||
log_method, log_entry, log_level)
|
log_method, log_entry, log_level)
|
||||||
if ret:
|
if ret:
|
||||||
|
|
|
@ -158,6 +158,12 @@ class HorizonMiddleware(object):
|
||||||
login_url = request.build_absolute_uri(auth_url)
|
login_url = request.build_absolute_uri(auth_url)
|
||||||
response = redirect_to_login(next_url, login_url=login_url,
|
response = redirect_to_login(next_url, login_url=login_url,
|
||||||
redirect_field_name=field_name)
|
redirect_field_name=field_name)
|
||||||
|
if isinstance(exception, exceptions.NotAuthorized):
|
||||||
|
logout_reason = _("Unauthorized. Please try logging in again.")
|
||||||
|
utils.add_logout_reason(request, response, logout_reason)
|
||||||
|
# delete messages, created in get_data() method
|
||||||
|
# since we are going to redirect user to the login page
|
||||||
|
response.delete_cookie('messages')
|
||||||
|
|
||||||
if request.is_ajax():
|
if request.is_ajax():
|
||||||
response_401 = http.HttpResponse(status=401)
|
response_401 = http.HttpResponse(status=401)
|
||||||
|
|
|
@ -17,9 +17,11 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.contrib.auth import REDIRECT_FIELD_NAME # noqa
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.forms import widgets
|
from django.forms import widgets
|
||||||
from django import http
|
from django import http
|
||||||
|
@ -886,9 +888,18 @@ class InstanceTests(helpers.TestCase):
|
||||||
|
|
||||||
url = reverse('horizon:project:instances:detail',
|
url = reverse('horizon:project:instances:detail',
|
||||||
args=[server.id])
|
args=[server.id])
|
||||||
res = self.client.get(url)
|
|
||||||
|
|
||||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
# Avoid the log message in the test
|
||||||
|
# when unauthorized exception will be logged
|
||||||
|
logging.disable(logging.ERROR)
|
||||||
|
res = self.client.get(url)
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
self.assertEqual(302, res.status_code)
|
||||||
|
self.assertEqual(('Location', settings.TESTSERVER +
|
||||||
|
settings.LOGIN_URL + '?' +
|
||||||
|
REDIRECT_FIELD_NAME + '=' + url),
|
||||||
|
res._headers.get('location', None),)
|
||||||
|
|
||||||
def test_instance_details_flavor_not_found(self):
|
def test_instance_details_flavor_not_found(self):
|
||||||
server = self.servers.first()
|
server = self.servers.first()
|
||||||
|
|
|
@ -17,7 +17,10 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth import REDIRECT_FIELD_NAME # noqa
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django import http
|
from django import http
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
@ -34,7 +37,8 @@ INDEX_URL = reverse('horizon:project:overview:index')
|
||||||
|
|
||||||
class UsageViewTests(test.TestCase):
|
class UsageViewTests(test.TestCase):
|
||||||
|
|
||||||
def _stub_nova_api_calls(self, nova_stu_enabled=True):
|
def _stub_nova_api_calls(self, nova_stu_enabled=True,
|
||||||
|
stu_exception=False):
|
||||||
self.mox.StubOutWithMock(api.nova, 'usage_get')
|
self.mox.StubOutWithMock(api.nova, 'usage_get')
|
||||||
self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
|
self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
|
||||||
self.mox.StubOutWithMock(api.nova, 'extension_supported')
|
self.mox.StubOutWithMock(api.nova, 'extension_supported')
|
||||||
|
@ -42,6 +46,9 @@ class UsageViewTests(test.TestCase):
|
||||||
'SimpleTenantUsage', IsA(http.HttpRequest)) \
|
'SimpleTenantUsage', IsA(http.HttpRequest)) \
|
||||||
.AndReturn(nova_stu_enabled)
|
.AndReturn(nova_stu_enabled)
|
||||||
|
|
||||||
|
if nova_stu_enabled and stu_exception:
|
||||||
|
self._nova_stu_enabled(stu_exception)
|
||||||
|
|
||||||
def _stub_cinder_api_calls(self):
|
def _stub_cinder_api_calls(self):
|
||||||
self.mox.StubOutWithMock(api.cinder, 'tenant_absolute_limits')
|
self.mox.StubOutWithMock(api.cinder, 'tenant_absolute_limits')
|
||||||
api.cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \
|
api.cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \
|
||||||
|
@ -64,6 +71,20 @@ class UsageViewTests(test.TestCase):
|
||||||
api.network.security_group_list(IsA(http.HttpRequest)) \
|
api.network.security_group_list(IsA(http.HttpRequest)) \
|
||||||
.AndReturn(self.q_secgroups.list())
|
.AndReturn(self.q_secgroups.list())
|
||||||
|
|
||||||
|
def _nova_stu_enabled(self, exception=False):
|
||||||
|
now = timezone.now()
|
||||||
|
start = datetime.datetime(now.year, now.month, 1, 0, 0, 0, 0)
|
||||||
|
end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)
|
||||||
|
|
||||||
|
if exception:
|
||||||
|
api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
|
||||||
|
start, end) \
|
||||||
|
.AndRaise(exception)
|
||||||
|
else:
|
||||||
|
api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
|
||||||
|
start, end) \
|
||||||
|
.AndReturn(api.nova.NovaUsage(self.usages.first()))
|
||||||
|
|
||||||
def test_usage(self):
|
def test_usage(self):
|
||||||
self._test_usage(nova_stu_enabled=True)
|
self._test_usage(nova_stu_enabled=True)
|
||||||
|
|
||||||
|
@ -150,32 +171,33 @@ class UsageViewTests(test.TestCase):
|
||||||
self.assertNotContains(res, 'form-inline')
|
self.assertNotContains(res, 'form-inline')
|
||||||
self.assertEqual(usages.limits['maxTotalFloatingIps'], 10)
|
self.assertEqual(usages.limits['maxTotalFloatingIps'], 10)
|
||||||
|
|
||||||
def test_unauthorized(self):
|
@test.create_stubs({api.nova: ('usage_get',
|
||||||
exc = self.exceptions.nova_unauthorized
|
'extension_supported')})
|
||||||
now = timezone.now()
|
def _stub_nova_api_calls_unauthorized(self, exception):
|
||||||
self._stub_nova_api_calls()
|
|
||||||
api.nova.extension_supported(
|
api.nova.extension_supported(
|
||||||
'SimpleTenantUsage', IsA(http.HttpRequest)) \
|
'SimpleTenantUsage', IsA(http.HttpRequest)) \
|
||||||
.AndReturn(True)
|
.AndReturn(True)
|
||||||
api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
|
self._nova_stu_enabled(exception)
|
||||||
datetime.datetime(now.year,
|
|
||||||
now.month,
|
def test_unauthorized(self):
|
||||||
1, 0, 0, 0, 0),
|
self._stub_nova_api_calls_unauthorized(
|
||||||
datetime.datetime(now.year,
|
self.exceptions.nova_unauthorized)
|
||||||
now.month,
|
|
||||||
now.day, 23, 59, 59, 0)) \
|
|
||||||
.AndRaise(exc)
|
|
||||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
|
|
||||||
.AndReturn(self.limits['absolute'])
|
|
||||||
self._stub_neutron_api_calls()
|
|
||||||
self._stub_cinder_api_calls()
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
url = reverse('horizon:project:overview:index')
|
url = reverse('horizon:project:overview:index')
|
||||||
|
|
||||||
|
# Avoid the log message in the test
|
||||||
|
# when unauthorized exception will be logged
|
||||||
|
logging.disable(logging.ERROR)
|
||||||
res = self.client.get(url)
|
res = self.client.get(url)
|
||||||
self.assertTemplateUsed(res, 'project/overview/usage.html')
|
logging.disable(logging.NOTSET)
|
||||||
self.assertMessageCount(res, error=1)
|
|
||||||
self.assertContains(res, 'Unauthorized:')
|
self.assertEqual(302, res.status_code)
|
||||||
|
self.assertEqual((
|
||||||
|
'Location', settings.TESTSERVER +
|
||||||
|
settings.LOGIN_URL + '?' +
|
||||||
|
REDIRECT_FIELD_NAME + '=' + url),
|
||||||
|
res._headers.get('location', None),)
|
||||||
|
|
||||||
def test_usage_csv(self):
|
def test_usage_csv(self):
|
||||||
self._test_usage_csv(nova_stu_enabled=True)
|
self._test_usage_csv(nova_stu_enabled=True)
|
||||||
|
|
Loading…
Reference in New Issue