diff --git a/awx/sso/middleware.py b/awx/sso/middleware.py index 1944ff4d0f..015e8fdd09 100644 --- a/awx/sso/middleware.py +++ b/awx/sso/middleware.py @@ -8,12 +8,14 @@ import urllib import six # Django +from django.conf import settings from django.utils.functional import LazyObject from django.shortcuts import redirect # Python Social Auth from social_core.exceptions import SocialAuthBaseException from social_core.utils import social_logger +from social_django import utils from social_django.middleware import SocialAuthExceptionMiddleware @@ -24,6 +26,19 @@ class SocialAuthMiddleware(SocialAuthExceptionMiddleware): request.session['social_auth_last_backend'] = callback_kwargs['backend'] def process_request(self, request): + if request.path.startswith('/sso'): + # django-social keeps a list of backends in memory that it gathers + # based on the value of settings.AUTHENTICATION_BACKENDS *at import + # time*: + # https://github.com/python-social-auth/social-app-django/blob/c1e2795b00b753d58a81fa6a0261d8dae1d9c73d/social_django/utils.py#L13 + # + # our settings.AUTHENTICATION_BACKENDS can *change* + # dynamically as Tower settings are changed (i.e., if somebody + # configures Github OAuth2 integration), so we need to + # _overwrite_ this in-memory value at the top of every request so + # that we have the latest version + # see: https://github.com/ansible/tower/issues/1979 + utils.BACKENDS = settings.AUTHENTICATION_BACKENDS token_key = request.COOKIES.get('token', '') token_key = urllib.quote(urllib.unquote(token_key).strip('"')) diff --git a/awx/wsgi.py b/awx/wsgi.py index e291a69d39..d351fed217 100644 --- a/awx/wsgi.py +++ b/awx/wsgi.py @@ -13,6 +13,7 @@ from django.core.wsgi import WSGIHandler # NOQA import django # NOQA from django.conf import settings # NOQA from django.urls import resolve # NOQA +import social_django # NOQA """ @@ -34,6 +35,11 @@ if MODE == 'production': logger.error("Missing or incorrect metadata for Tower version. Ensure Tower was installed using the setup playbook.") raise Exception("Missing or incorrect metadata for Tower version. Ensure Tower was installed using the setup playbook.") +if social_django.__version__ != '2.1.0': + raise RuntimeError("social_django version other than 2.1.0 detected {}. \ + Confirm that per-request social_django.utils.BACKENDS override \ + still works".format(social_django.__version__)) + if django.__version__ != '1.11.11': raise RuntimeError("Django version other than 1.11.11 detected {}. \