From c925e00266d8412c0a71deab6533b5b4e86f695c Mon Sep 17 00:00:00 2001 From: Robert Raposa Date: Tue, 18 Apr 2023 16:25:48 -0400 Subject: [PATCH] feat: add edx_drf_extensions_version custom attribute (#331) Add edx_drf_extensions_version custom attribute to help monitor rollout of upgrades to this library. Requires use of RequestCustomAttributesMiddleware. Versions before 8.7.0 will not include this attribute, but should include `request_auth_type_guess`. --- CHANGELOG.rst | 8 +++++++ edx_rest_framework_extensions/__init__.py | 2 +- edx_rest_framework_extensions/middleware.py | 8 +++++++ .../tests/test_middleware.py | 21 +++++++++++++++---- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 05a1aab8..cb49e6c2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,6 +12,14 @@ Change Log Unreleased ---------- +[8.7.0] - 2023-04-14 +-------------------- + +Added +~~~~~ + +* Add ``edx_drf_extensions_version`` to help with rollout of changes in this library across services. + Removed ~~~~~~~ diff --git a/edx_rest_framework_extensions/__init__.py b/edx_rest_framework_extensions/__init__.py index 0c6623c2..ac161be0 100644 --- a/edx_rest_framework_extensions/__init__.py +++ b/edx_rest_framework_extensions/__init__.py @@ -1,3 +1,3 @@ """ edx Django REST Framework extensions. """ -__version__ = '8.6.0' # pragma: no cover +__version__ = '8.7.0' # pragma: no cover diff --git a/edx_rest_framework_extensions/middleware.py b/edx_rest_framework_extensions/middleware.py index 56c60c06..bfe4745d 100644 --- a/edx_rest_framework_extensions/middleware.py +++ b/edx_rest_framework_extensions/middleware.py @@ -7,6 +7,7 @@ from edx_django_utils import monitoring from edx_django_utils.cache import DEFAULT_REQUEST_CACHE +import edx_rest_framework_extensions from edx_rest_framework_extensions.auth.jwt.constants import USE_JWT_COOKIE_HEADER from edx_rest_framework_extensions.auth.jwt.cookies import jwt_cookie_name @@ -72,6 +73,13 @@ def _set_all_request_attributes(self, request): """ Sets all the request custom attributes """ + # .. custom_attribute_name: edx_drf_extensions_version + # .. custom_attribute_description: The version of the edx-drf-extensions library installed, which may be + # useful when trying to rollout important changes to all services. Note that RequestCustomAttributesMiddleware + # must be installed for this to work. Also, versions before 8.7.0 will not include this attribute, but + # should have ``request_auth_type_guess``. + monitoring.set_custom_attribute('edx_drf_extensions_version', edx_rest_framework_extensions.__version__) + self._set_request_auth_type_guess_attribute(request) self._set_request_user_agent_attributes(request) self._set_request_referer_attribute(request) diff --git a/edx_rest_framework_extensions/tests/test_middleware.py b/edx_rest_framework_extensions/tests/test_middleware.py index 5da0d999..f3235346 100644 --- a/edx_rest_framework_extensions/tests/test_middleware.py +++ b/edx_rest_framework_extensions/tests/test_middleware.py @@ -1,6 +1,7 @@ """ Unit tests for middlewares. """ +import re from unittest.mock import call, patch import ddt @@ -25,18 +26,30 @@ def setUp(self): self.request = RequestFactory().get('/') self.middleware = RequestCustomAttributesMiddleware() # pylint: disable=no-value-for-parameter + @patch('edx_django_utils.monitoring.set_custom_attribute') + def test_edx_drf_extensions_version_attribute(self, mock_set_custom_attribute): + self.request.user = AnonymousUser() + + self.middleware.process_response(self.request, None) + # if call_args_list contains call('edx_drf_extensions_version', '8.7.0'), then version_list = ['8.7.0'] + version_list = [ + x.args[1] for x in mock_set_custom_attribute.call_args_list if x.args[0] == 'edx_drf_extensions_version' + ] + assert len(version_list) == 1 + assert re.search(r'\d+\.\d+\.\d+', version_list[0]) + @patch('edx_django_utils.monitoring.set_custom_attribute') def test_request_auth_type_guess_anonymous_attribute(self, mock_set_custom_attribute): self.request.user = AnonymousUser() self.middleware.process_response(self.request, None) - mock_set_custom_attribute.assert_called_once_with('request_auth_type_guess', 'unauthenticated') + mock_set_custom_attribute.assert_called_with('request_auth_type_guess', 'unauthenticated') @patch('edx_django_utils.monitoring.set_custom_attribute') def test_request_no_headers(self, mock_set_custom_attribute): self.request.user = None self.middleware.process_response(self.request, None) - mock_set_custom_attribute.assert_called_once_with('request_auth_type_guess', 'no-user') + mock_set_custom_attribute.assert_called_with('request_auth_type_guess', 'no-user') @patch('edx_django_utils.monitoring.set_custom_attribute') def test_request_blank_headers(self, mock_set_custom_attribute): @@ -45,7 +58,7 @@ def test_request_blank_headers(self, mock_set_custom_attribute): self.request.META['HTTP_AUTHORIZATION'] = '' self.middleware.process_response(self.request, None) - mock_set_custom_attribute.assert_called_once_with('request_auth_type_guess', 'no-user') + mock_set_custom_attribute.assert_called_with('request_auth_type_guess', 'no-user') @patch('edx_django_utils.monitoring.set_custom_attribute') def test_request_referer_attribute(self, mock_set_custom_attribute): @@ -224,4 +237,4 @@ def test_request_auth_type_guess_anonymous_attribute(self, mock_set_custom_attri self.request.user = AnonymousUser() self.middleware.process_response(self.request, None) - mock_set_custom_attribute.assert_called_once_with('request_auth_type_guess', 'unauthenticated') + mock_set_custom_attribute.assert_called_with('request_auth_type_guess', 'unauthenticated')