Fix django.contrib.auth.middleware monkey patching

The "request" attribute is not available in
openstack_auth.backend.KeystoneBackend.get_user when session data is restored
and it's the first request to happen after a server restart.

As stated by the function document, the "request" attribute needs to be
monkey-patched by openstack_auth.utils.patch_middleware_get_user
for this function to work properly.

This should happen in openstack_auth.urls at import time. But there is nowhere
in Horizon where this module is imported at startup. It's only introspected
by openstack_dashboard.urls due to AUTHENTICATION_URLS setting.

Without this monkey-patching, the whole authentication mechanism falls back
to "AnonymousUser" and you will get redirected to the login page due
to horizon.exceptions.NotAuthenticated being raised by
horizon.decorators.require_auth as request.user.is_authenticated will be False.

But if a user requests a page under auth/, it will have the side-effect of
monkey-patching django.contrib.auth.middleware as expected. This means that
once this request is completed, all following requests to pages other than
the ones under auth/ will have there sessions properly restored and
you will be properly authenticated.

Therefore this change introduces a dummy middleware which sole purpose is
to perform this monkey-patching as early as possible.

There is also some cleanup to get rid of the previous attempts at
monkeypatching.

Closes-bug: #1764622

[backport specific notice]
Queens horizon supports Django 1.8 and 1.11.
The key point is Django 2.0 is not supported.
Django 2.0 dropped the legacy Django middleware interface and
the new interface is not supported in Django 1.8.
Thus, this backport changes OpenstackAuthMonkeyPatchMiddleware in
openstack_auth/middlware.py to use the legacy middleware interface.

Conflicts:
	openstack_dashboard/settings.py
	openstack_dashboard/test/helpers.py

Change-Id: Ib9912090a87b716e7f5710f6f360b0df168ec2e3
(cherry picked from commit 0d16361326)
(cherry picked from commit 8851866aad)
This commit is contained in:
Mathieu Gagné 2018-10-31 22:24:31 -04:00 committed by Akihiro Motoki
parent c261df6ef4
commit 6ae1f5e21d
8 changed files with 25 additions and 9 deletions

View File

@ -63,6 +63,7 @@ INSTALLED_APPS = (
)
MIDDLEWARE_CLASSES = (
'openstack_auth.middleware.OpenstackAuthMonkeyPatchMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',

View File

@ -0,0 +1,20 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack_auth import utils
# NOTE: The main role of this middleware is to call this.
utils.patch_middleware_get_user()
class OpenstackAuthMonkeyPatchMiddleware(object):
pass

View File

@ -28,6 +28,7 @@ INSTALLED_APPS = [
]
MIDDLEWARE_CLASSES = [
'openstack_auth.middleware.OpenstackAuthMonkeyPatchMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',

View File

@ -15,13 +15,9 @@ from django.conf.urls import include
from django.conf.urls import url
from django.views import generic
from openstack_auth import utils
from openstack_auth import views
utils.patch_middleware_get_user()
urlpatterns = [
url(r"", include('openstack_auth.urls')),
url(r"^websso/$", views.websso, name='websso'),

View File

@ -16,8 +16,6 @@ from django.conf.urls import url
from openstack_auth import utils
from openstack_auth import views
utils.patch_middleware_get_user()
urlpatterns = [
url(r"^login/$", views.login, name='login'),

View File

@ -37,8 +37,8 @@ We need the request object to get the user, so we'll slightly modify the
existing django.contrib.auth.get_user method. To do so we update the
auth middleware to point to our overridden method.
Calling the "patch_middleware_get_user" method somewhere like our urls.py
file takes care of hooking it in appropriately.
Calling "patch_middleware_get_user" is done in our custom middleware at
"openstack_auth.middleware" to monkeypatch the code in before it is needed.
"""

View File

@ -108,6 +108,7 @@ OPENSTACK_IMAGE_BACKEND = {
}
MIDDLEWARE_CLASSES = (
'openstack_auth.middleware.OpenstackAuthMonkeyPatchMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',

View File

@ -466,7 +466,6 @@ class APITestCase(TestCase):
"""
def setUp(self):
super(APITestCase, self).setUp()
utils.patch_middleware_get_user()
def fake_keystoneclient(request, admin=False):
"""Returns the stub keystoneclient.