diff --git a/awx/main/middleware.py b/awx/main/middleware.py index 5a0f587440..86bb58e33e 100644 --- a/awx/main/middleware.py +++ b/awx/main/middleware.py @@ -18,6 +18,7 @@ from django.db import IntegrityError, connection from django.utils.functional import curry from django.shortcuts import get_object_or_404, redirect from django.apps import apps +from django.utils.deprecation import MiddlewareMixin from django.utils.translation import ugettext_lazy as _ from django.urls import reverse, resolve @@ -31,7 +32,7 @@ analytics_logger = logging.getLogger('awx.analytics.activity_stream') perf_logger = logging.getLogger('awx.analytics.performance') -class TimingMiddleware(threading.local): +class TimingMiddleware(threading.local, MiddlewareMixin): dest = '/var/log/tower/profile' @@ -64,11 +65,12 @@ class TimingMiddleware(threading.local): return filepath -class ActivityStreamMiddleware(threading.local): +class ActivityStreamMiddleware(threading.local, MiddlewareMixin): - def __init__(self): + def __init__(self, get_response=None): self.disp_uid = None self.instance_ids = [] + super().__init__(get_response) def process_request(self, request): if hasattr(request, 'user') and hasattr(request.user, 'is_authenticated') and request.user.is_authenticated(): @@ -118,7 +120,7 @@ class ActivityStreamMiddleware(threading.local): self.instance_ids.append(instance.id) -class SessionTimeoutMiddleware(object): +class SessionTimeoutMiddleware(MiddlewareMixin): """ Resets the session timeout for both the UI and the actual session for the API to the value of SESSION_COOKIE_AGE on every request if there is a valid session. @@ -151,9 +153,9 @@ def _customize_graph(): settings.NAMED_URL_GRAPH[Instance].add_bindings() -class URLModificationMiddleware(object): +class URLModificationMiddleware(MiddlewareMixin): - def __init__(self): + def __init__(self, get_response=None): models = [m for m in apps.get_app_config('main').get_models() if hasattr(m, 'get_absolute_url')] generate_graph(models) _customize_graph() @@ -177,6 +179,7 @@ class URLModificationMiddleware(object): category=_('Named URL'), category_slug='named-url', ) + super().__init__(get_response) def _named_url_to_pk(self, node, named_url): kwargs = {} @@ -207,7 +210,7 @@ class URLModificationMiddleware(object): request.path_info = new_path -class MigrationRanCheckMiddleware(object): +class MigrationRanCheckMiddleware(MiddlewareMixin): def process_request(self, request): executor = MigrationExecutor(connection) diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 85d56728a3..011b6d086d 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -251,29 +251,11 @@ TEMPLATES = [ }, ] -MIDDLEWARE_CLASSES = ( # NOQA - 'awx.main.middleware.TimingMiddleware', - 'awx.main.middleware.MigrationRanCheckMiddleware', - 'corsheaders.middleware.CorsMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.locale.LocaleMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'awx.main.middleware.ActivityStreamMiddleware', - 'awx.sso.middleware.SocialAuthMiddleware', - 'crum.CurrentRequestUserMiddleware', - 'awx.main.middleware.URLModificationMiddleware', - 'awx.main.middleware.SessionTimeoutMiddleware', -) - - ROOT_URLCONF = 'awx.urls' WSGI_APPLICATION = 'awx.wsgi.application' -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.messages', @@ -294,7 +276,7 @@ INSTALLED_APPS = ( 'awx.ui', 'awx.sso', 'solo' -) +] INTERNAL_IPS = ('127.0.0.1',) @@ -447,16 +429,6 @@ AWX_ISOLATED_VERBOSITY = 0 # } # } -# Use Django-Debug-Toolbar if installed. -try: - import debug_toolbar - INSTALLED_APPS += (debug_toolbar.__name__,) -except ImportError: - pass - -DEBUG_TOOLBAR_CONFIG = { - 'ENABLE_STACKTRACES' : True, -} DEVSERVER_DEFAULT_ADDR = '0.0.0.0' DEVSERVER_DEFAULT_PORT = '8013' @@ -628,7 +600,7 @@ AWX_REBUILD_SMART_MEMBERSHIP = False ALLOW_JINJA_IN_EXTRA_VARS = 'template' # Enable dynamically pulling roles from a requirement.yml file -# when updating SCM projects +# when updating SCM projects # Note: This setting may be overridden by database settings. AWX_ROLES_ENABLED = True @@ -1211,3 +1183,20 @@ AWX_REQUEST_PROFILE = False # Delete temporary directories created to store playbook run-time AWX_CLEANUP_PATHS = True + +MIDDLEWARE = [ + 'awx.main.middleware.TimingMiddleware', + 'awx.main.middleware.MigrationRanCheckMiddleware', + 'corsheaders.middleware.CorsMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'awx.main.middleware.ActivityStreamMiddleware', + 'awx.sso.middleware.SocialAuthMiddleware', + 'crum.CurrentRequestUserMiddleware', + 'awx.main.middleware.URLModificationMiddleware', + 'awx.main.middleware.SessionTimeoutMiddleware', +] diff --git a/awx/settings/development.py b/awx/settings/development.py index 0de8314f28..717d8d52dd 100644 --- a/awx/settings/development.py +++ b/awx/settings/development.py @@ -93,7 +93,7 @@ INSIGHTS_TRACKING_STATE = False # Use Django-Jenkins if installed. Only run tests for awx.main app. try: import django_jenkins - INSTALLED_APPS += (django_jenkins.__name__,) # noqa + INSTALLED_APPS += [django_jenkins.__name__,] # noqa PROJECT_APPS = ('awx.main.tests', 'awx.api.tests',) except ImportError: pass @@ -112,7 +112,18 @@ if 'django_jenkins' in INSTALLED_APPS: PEP8_RCFILE = "setup.cfg" PYLINT_RCFILE = ".pylintrc" -INSTALLED_APPS += ('rest_framework_swagger',) +INSTALLED_APPS += [ # NOQA + 'rest_framework_swagger', + 'debug_toolbar', +] + +MIDDLEWARE += [ # NOQA + 'debug_toolbar.middleware.DebugToolbarMiddleware', +] + +DEBUG_TOOLBAR_CONFIG = { + 'ENABLE_STACKTRACES' : True, +} # Configure a default UUID for development only. SYSTEM_UUID = '00000000-0000-0000-0000-000000000000' diff --git a/awx/sso/middleware.py b/awx/sso/middleware.py index aa0a81fd29..4edd4c4a2e 100644 --- a/awx/sso/middleware.py +++ b/awx/sso/middleware.py @@ -4,8 +4,6 @@ # Python import urllib.parse -# Six - # Django from django.conf import settings from django.utils.functional import LazyObject @@ -20,10 +18,6 @@ from social_django.middleware import SocialAuthExceptionMiddleware class SocialAuthMiddleware(SocialAuthExceptionMiddleware): - def process_view(self, request, callback, callback_args, callback_kwargs): - if request.path.startswith('/sso/login/'): - 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 @@ -53,6 +47,11 @@ class SocialAuthMiddleware(SocialAuthExceptionMiddleware): request.user = request.user._wrapped request.session.pop('social_auth_error', None) request.session.pop('social_auth_last_backend', None) + return self.get_response(request) + + def process_view(self, request, callback, callback_args, callback_kwargs): + if request.path.startswith('/sso/login/'): + request.session['social_auth_last_backend'] = callback_kwargs['backend'] def process_exception(self, request, exception): strategy = getattr(request, 'social_strategy', None) diff --git a/awx/wsgi.py b/awx/wsgi.py index 656c96460b..13f8b08198 100644 --- a/awx/wsgi.py +++ b/awx/wsgi.py @@ -8,11 +8,10 @@ from awx import __version__ as tower_version from awx import prepare_env, MODE prepare_env() - -from django.core.wsgi import WSGIHandler # NOQA import django # NOQA from django.conf import settings # NOQA from django.urls import resolve # NOQA +from django.core.wsgi import get_wsgi_application # NOQA import social_django # NOQA @@ -41,41 +40,12 @@ if social_django.__version__ != '2.1.0': still works".format(social_django.__version__)) -if django.__version__ != '1.11.20': - raise RuntimeError("Django version other than 1.11.20 detected {}. \ +if not django.__version__.startswith('1.'): + raise RuntimeError("Django version other than 1.XX detected {}. \ Inherit from WSGIHandler to support short-circuit Django Middleware. \ - This is known to work for Django 1.11.20 and may not work with other, \ + This is known to work for Django 1.XX and may not work with other, \ even minor, versions.".format(django.__version__)) -if settings.MIDDLEWARE: - raise RuntimeError("MIDDLEWARE setting detected. \ - The 'migration in progress' view feature short-circuits OLD Django \ - MIDDLEWARE_CLASSES behavior. With the new Django MIDDLEWARE beahvior \ - it's possible to short-ciruit the middleware onion through supported \ - middleware mechanisms. Further, from django.core.wsgi.get_wsgi_application() \ - should be called to get an instance of WSGIHandler().") - - -class AWXWSGIHandler(WSGIHandler): - def _legacy_get_response(self, request): - try: - # resolve can raise a 404, in that case, pass through to the - # "normal" middleware - if getattr(resolve(request.path), 'url_name', '') == 'migrations_notran': - # short-circuit middleware - request._cors_enabled = False - return self._get_response(request) - except django.urls.Resolver404: - pass - # fall through to middle-ware - return super(AWXWSGIHandler, self)._legacy_get_response(request) - - # Return the default Django WSGI application. -def get_wsgi_application(): - django.setup(set_prefix=False) - return AWXWSGIHandler() - - application = get_wsgi_application()