Show NotAuthorized error message on a separate page

Change-Id: I02d9d610a0e5feff7da14f86d003ec21010ab26a
Closes-Bug: #1709077
This commit is contained in:
Ivan Kolodyazhny 2017-08-07 15:43:38 +03:00
parent 50354f0248
commit 8f4e02c96d
7 changed files with 27 additions and 49 deletions

View File

@ -226,19 +226,8 @@ def handle_unauthorized(request, message, redirect, ignore, escalate, handled,
# some clients, so let's define our own fallback.
fallback = _("Unauthorized. Please try logging in again.")
messages.error(request, message or fallback)
# Escalation means logging the user out and raising NotAuthorized
# so the middleware will redirect them appropriately.
if escalate:
# Prevents creation of circular import. django.contrib.auth
# requires openstack_dashboard.settings to be loaded (by trying to
# access settings.CACHES in django.core.caches) while
# openstack_dashboard.settings requires django.contrib.auth to be
# loaded while importing openstack_auth.utils
from django.contrib.auth import logout
logout(request)
raise NotAuthorized
# Otherwise continue and present our "unauthorized" error message.
return NotAuthorized
# Continue and present our "unauthorized" error message.
raise NotAuthorized
def handle_notfound(request, message, redirect, ignore, escalate, handled,

View File

@ -30,7 +30,6 @@ from django import http
from django import shortcuts
from django.utils.encoding import iri_to_uri
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from openstack_auth import views as auth_views
@ -128,12 +127,9 @@ class HorizonMiddleware(object):
response = redirect_to_login(next_url, login_url=login_url,
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,
'error')
# delete messages, created in get_data() method
# since we are going to redirect user to the login page
response.delete_cookie('messages')
return shortcuts.render(request, 'not_authorized.html',
status=403)
if request.is_ajax():
response_401 = http.HttpResponse(status=401)

View File

@ -0,0 +1,10 @@
{% extends 'base.html' %}
{% load i18n %}
{% block breadcrumb_nav %}
{% endblock %}
{% block title %}{% trans "Unauthorized. Please try logging in again." %}{% endblock %}
{% block main %}
{% trans "You are mot authorized to access this page" %}
<a href="{% url 'login' %}">{% trans "Login" %}</a>
{% endblock %}

View File

@ -277,18 +277,17 @@ class HorizonTests(BaseHorizonTests):
self.assertQuerysetEqual(self.user.get_all_permissions(), [])
resp = self.client.get(panel.get_absolute_url())
self.assertEqual(302, resp.status_code)
self.assertEqual(403, resp.status_code)
resp = self.client.get(panel.get_absolute_url(),
follow=False,
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(401, resp.status_code)
self.assertEqual(403, resp.status_code)
# Test insufficient permissions for logged-in user
resp = self.client.get(panel.get_absolute_url(), follow=True)
self.assertEqual(200, resp.status_code)
self.assertTemplateUsed(resp, "auth/login.html")
self.assertContains(resp, "Login as different user", 1, 200)
self.assertEqual(403, resp.status_code)
self.assertTemplateUsed(resp, "not_authorized.html")
# Set roles for admin user
self.set_permissions(permissions=['test'])
@ -440,18 +439,17 @@ class CustomPermissionsTests(BaseHorizonTests):
self.assertQuerysetEqual(self.user.get_all_permissions(), [])
resp = self.client.get(panel.get_absolute_url())
self.assertEqual(302, resp.status_code)
self.assertEqual(403, resp.status_code)
resp = self.client.get(panel.get_absolute_url(),
follow=False,
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(401, resp.status_code)
self.assertEqual(403, resp.status_code)
# Test customized permissions for logged-in user
resp = self.client.get(panel.get_absolute_url(), follow=True)
self.assertEqual(200, resp.status_code)
self.assertTemplateUsed(resp, "auth/login.html")
self.assertContains(resp, "Login as different user", 1, 200)
self.assertEqual(403, resp.status_code)
self.assertTemplateUsed(resp, "not_authorized.html")
# Set roles for admin user
self.set_permissions(permissions=['test'])

View File

@ -41,7 +41,7 @@ class MiddlewareTests(test.TestCase):
request = self.factory.post(url)
mw = middleware.HorizonMiddleware()
resp = mw.process_exception(request, exceptions.NotAuthorized())
resp = mw.process_exception(request, exceptions.NotAuthenticated())
resp.client = self.client
if django.VERSION >= (1, 9):

View File

@ -23,7 +23,6 @@ import sys
import django
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.urlresolvers import reverse
from django.forms import widgets
from django import http
@ -1155,11 +1154,9 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
def test_instance_details_unauthorized(self):
server = self.servers.first()
api.nova.server_get(IsA(http.HttpRequest), server.id)\
.AndRaise(self.exceptions.nova_unauthorized)
self.mox.ReplayAll()
url = reverse('horizon:project:instances:detail',
url = reverse('horizon:admin:instances:detail',
args=[server.id])
# Avoid the log message in the test
@ -1168,11 +1165,7 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
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),)
self.assertEqual(403, res.status_code)
def test_instance_details_flavor_not_found(self):
server = self.servers.first()

View File

@ -19,8 +19,6 @@
import datetime
import logging
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.urlresolvers import reverse
from django import http
from django.test.utils import override_settings
@ -166,11 +164,9 @@ class UsageViewTests(test.TestCase):
self._nova_stu_enabled(exception)
def test_unauthorized(self):
self._stub_nova_api_calls_unauthorized(
self.exceptions.nova_unauthorized)
self.mox.ReplayAll()
url = reverse('horizon:project:overview:index')
url = reverse('horizon:admin:volumes:index')
# Avoid the log message in the test
# when unauthorized exception will be logged
@ -178,11 +174,7 @@ class UsageViewTests(test.TestCase):
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),)
self.assertEqual(403, res.status_code)
def test_usage_csv(self):
self._test_usage_csv(nova_stu_enabled=True)