Merge branch 'master' into sameeramin/ENT-10591
This commit is contained in:
@@ -869,9 +869,6 @@ MIDDLEWARE = [
|
||||
'edx_django_utils.monitoring.FrontendMonitoringMiddleware',
|
||||
'edx_django_utils.monitoring.MonitoringMemoryMiddleware',
|
||||
|
||||
# Before anything that looks at cookies, especially the session middleware
|
||||
'openedx.core.djangoapps.cookie_metadata.middleware.CookieNameChange',
|
||||
|
||||
'openedx.core.djangoapps.header_control.middleware.HeaderControlMiddleware',
|
||||
'django.middleware.cache.UpdateCacheMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
@@ -1196,6 +1193,10 @@ COURSE_METADATA_EXPORT_BUCKET = ''
|
||||
|
||||
ALTERNATE_WORKER_QUEUES = 'lms'
|
||||
|
||||
# .. setting_name: STATIC_URL_BASE
|
||||
# .. setting_default: "/static/"
|
||||
# .. setting_description: The CMS uses this to construct ``STATIC_URL`` by appending
|
||||
# a slash (if needed) and then ``studio/``.
|
||||
STATIC_URL_BASE = '/static/'
|
||||
|
||||
X_FRAME_OPTIONS = 'DENY'
|
||||
|
||||
@@ -1920,6 +1920,10 @@ MANAGERS = ADMINS
|
||||
# Static content
|
||||
STATIC_URL = '/static/'
|
||||
STATIC_ROOT = os.environ.get('STATIC_ROOT_LMS', ENV_ROOT / "staticfiles")
|
||||
# .. setting_name: STATIC_URL_BASE
|
||||
# .. setting_default: "/static/"
|
||||
# .. setting_description: The LMS uses this to construct ``STATIC_URL`` by appending
|
||||
# a slash (if needed).
|
||||
STATIC_URL_BASE = '/static/'
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
@@ -2251,9 +2255,6 @@ MIDDLEWARE = [
|
||||
'edx_django_utils.monitoring.DeploymentMonitoringMiddleware',
|
||||
'edx_django_utils.monitoring.FrontendMonitoringMiddleware',
|
||||
|
||||
# Before anything that looks at cookies, especially the session middleware
|
||||
'openedx.core.djangoapps.cookie_metadata.middleware.CookieNameChange',
|
||||
|
||||
# Monitoring and logging for ignored errors
|
||||
'openedx.core.lib.request_utils.IgnoredErrorMiddleware',
|
||||
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
"""Middleware to change name of an incoming cookie"""
|
||||
from django.conf import settings
|
||||
|
||||
from edx_django_utils.monitoring import set_custom_attribute
|
||||
|
||||
|
||||
class CookieNameChange:
|
||||
"""Changes name of an incoming cookie"""
|
||||
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
"""
|
||||
Changes the names of a cookie in request.COOKIES
|
||||
|
||||
For this middleware to run:
|
||||
- set COOKIE_NAME_CHANGE_ACTIVATE = True
|
||||
- COOKIE_NAME_CHANGE_EXPAND_INFO is a dict and has following info:
|
||||
- "current": Cookie name that will be used by relying code
|
||||
- "alternate": Other cookie name, to be renamed to current name if present
|
||||
|
||||
Actions taken by middleware, during request phase:
|
||||
- Delete alternate-name cookie from request.COOKIES
|
||||
- Preserve any cookie with current name, or create one with value of
|
||||
cookie with alternate name (if alt cookie was present)
|
||||
|
||||
To perform a seamless name change for a cookie, follow this
|
||||
expand-contract procedure:
|
||||
|
||||
1. Baseline configuration::
|
||||
|
||||
SOME_COOKIE_NAME: old
|
||||
|
||||
2. Enable servers to understand both names by renaming the *new* name
|
||||
to the *old* (current) name, which should have no immediate effect::
|
||||
|
||||
COOKIE_NAME_CHANGE_ACTIVATE: True
|
||||
COOKIE_NAME_CHANGE_EXPAND_INFO:
|
||||
current: old
|
||||
alternate: new
|
||||
SOME_COOKIE_NAME: old
|
||||
|
||||
3. Swap the new and old cookie names in all three places they occur (the
|
||||
main setting and the two dictionary elements), now that all servers
|
||||
are capable of reading either name::
|
||||
|
||||
COOKIE_NAME_CHANGE_ACTIVATE: True
|
||||
COOKIE_NAME_CHANGE_EXPAND_INFO:
|
||||
current: new
|
||||
alternate: old
|
||||
SOME_COOKIE_NAME: new
|
||||
|
||||
4. After some time period to allow old cookies to age out, remove the
|
||||
transition settings::
|
||||
|
||||
SOME_COOKIE_NAME: new
|
||||
"""
|
||||
|
||||
# .. toggle_name: COOKIE_NAME_CHANGE_ACTIVATE
|
||||
# .. toggle_implementation: DjangoSetting
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: Used to enable CookieNameChange middleware which changes a cookie name in request.COOKIES
|
||||
# .. toggle_warning: This should be set at the same time you set COOKIE_NAME_CHANGE_EXPAND_INFO setting
|
||||
# .. toggle_use_cases: temporary
|
||||
# .. toggle_creation_date: 2021-08-04
|
||||
# .. toggle_target_removal_date: 2021-10-01
|
||||
# .. toggle_tickets: https://openedx.atlassian.net/browse/ARCHBOM-1872
|
||||
if getattr(settings, "COOKIE_NAME_CHANGE_ACTIVATE", False):
|
||||
alt_cookie_in_request = False
|
||||
expand_settings = getattr(settings, "COOKIE_NAME_CHANGE_EXPAND_INFO", None)
|
||||
|
||||
if (
|
||||
expand_settings is not None
|
||||
and isinstance(expand_settings, dict)
|
||||
and "current" in expand_settings
|
||||
and "alternate" in expand_settings
|
||||
):
|
||||
if expand_settings["alternate"] in request.COOKIES:
|
||||
alt_cookie_in_request = True
|
||||
alt_cookie_value = request.COOKIES[expand_settings["alternate"]]
|
||||
del request.COOKIES[expand_settings["alternate"]]
|
||||
# Adding custom attribute: cookie.change_name
|
||||
# if cookie.change_name in transaction and equal 0,
|
||||
# cookie with alternate name was detected and deleted
|
||||
# if cookie.change_name in transaction and equal 1,
|
||||
# cookie with current name was added
|
||||
set_custom_attribute("cookie.change_name", 0)
|
||||
|
||||
if (
|
||||
expand_settings["current"] not in request.COOKIES
|
||||
and alt_cookie_in_request
|
||||
):
|
||||
request.COOKIES[expand_settings["current"]] = alt_cookie_value
|
||||
set_custom_attribute("cookie.change_name", 1)
|
||||
|
||||
response = self.get_response(request)
|
||||
return response
|
||||
@@ -1,109 +0,0 @@
|
||||
"""
|
||||
Test Module to test CookieNameChange class
|
||||
"""
|
||||
from unittest.mock import Mock
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
from ..middleware import CookieNameChange
|
||||
|
||||
|
||||
class TestCookieNameChange(TestCase):
|
||||
"""
|
||||
Test class for CookieNameChange
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.mock_response = Mock()
|
||||
self.cookie_name_change_middleware = CookieNameChange(self.mock_response)
|
||||
self.mock_request = Mock()
|
||||
|
||||
self.old_value = "." * 100
|
||||
self.old_key = 'a'
|
||||
self.extra_cookies = {
|
||||
"_b": "." * 13,
|
||||
"_c_": "." * 13,
|
||||
"a.b": "." * 10,
|
||||
}
|
||||
self.old_dict = {
|
||||
self.old_key: self.old_value,
|
||||
}
|
||||
|
||||
self.expand_settings = {
|
||||
"alternate": self.old_key,
|
||||
"current": "b",
|
||||
}
|
||||
|
||||
def test_cookie_swap(self):
|
||||
"""Check to make sure self.Middleware correctly swaps keys"""
|
||||
|
||||
self.old_dict.update(self.extra_cookies)
|
||||
|
||||
self.mock_request.COOKIES = self.old_dict.copy()
|
||||
|
||||
with self.settings(
|
||||
COOKIE_NAME_CHANGE_ACTIVATE=True
|
||||
), self.settings(COOKIE_NAME_CHANGE_EXPAND_INFO=self.expand_settings):
|
||||
self.cookie_name_change_middleware(self.mock_request)
|
||||
|
||||
assert self.expand_settings["alternate"] not in self.mock_request.COOKIES.keys()
|
||||
assert self.expand_settings["current"] in self.mock_request.COOKIES.keys()
|
||||
assert self.mock_request.COOKIES[self.expand_settings["current"]] == self.old_value
|
||||
test_dict = self.extra_cookies.copy()
|
||||
test_dict[self.expand_settings['current']] = self.old_value
|
||||
assert self.mock_request.COOKIES == test_dict
|
||||
|
||||
# make sure response function is called once
|
||||
self.mock_response.assert_called_once()
|
||||
|
||||
def test_cookie_no_swap(self):
|
||||
"""Make sure self.cookie_name_change_middleware does not change cookie if current cookie is already present"""
|
||||
|
||||
new_value = "." * 13
|
||||
no_change_cookies = {
|
||||
self.expand_settings['current']: new_value,
|
||||
"_c_": "." * 13,
|
||||
"a.b": "." * 10,
|
||||
}
|
||||
|
||||
self.old_dict.update(no_change_cookies)
|
||||
|
||||
self.mock_request.COOKIES = self.old_dict.copy()
|
||||
|
||||
with self.settings(
|
||||
COOKIE_NAME_CHANGE_ACTIVATE=True
|
||||
), self.settings(COOKIE_NAME_CHANGE_EXPAND_INFO=self.expand_settings):
|
||||
self.cookie_name_change_middleware(self.mock_request)
|
||||
|
||||
assert self.expand_settings["alternate"] not in self.mock_request.COOKIES.keys()
|
||||
assert self.expand_settings["current"] in self.mock_request.COOKIES.keys()
|
||||
assert self.mock_request.COOKIES[self.expand_settings["current"]] == new_value
|
||||
assert self.mock_request.COOKIES == no_change_cookies
|
||||
|
||||
# make sure response function is called once
|
||||
self.mock_response.assert_called_once()
|
||||
|
||||
def test_does_nothing(self):
|
||||
"""Make sure turning off toggle turns off self.cookie_name_change_middleware"""
|
||||
|
||||
new_value = "." * 13
|
||||
no_change_cookies = {
|
||||
self.expand_settings['current']: new_value,
|
||||
"_c_": "." * 13,
|
||||
"a.b": "." * 10,
|
||||
}
|
||||
self.old_dict.update(no_change_cookies)
|
||||
|
||||
self.mock_request.COOKIES = self.old_dict.copy()
|
||||
|
||||
with self.settings(
|
||||
COOKIE_NAME_CHANGE_ACTIVATE=False
|
||||
), self.settings(COOKIE_NAME_CHANGE_EXPAND_INFO=self.expand_settings):
|
||||
self.cookie_name_change_middleware(self.mock_request)
|
||||
|
||||
assert self.mock_request.COOKIES == self.old_dict
|
||||
|
||||
# make sure response function is called once
|
||||
self.mock_response.assert_called_once()
|
||||
Reference in New Issue
Block a user