Make SessionMiddleware Microsite aware
This commit is contained in:
@@ -47,6 +47,15 @@ def get_value(val_name, default=None):
|
||||
return configuration.get(val_name, default)
|
||||
|
||||
|
||||
def has_override_value(val_name):
|
||||
"""
|
||||
Returns True/False whether a Microsite has a definition for the
|
||||
specified named value
|
||||
"""
|
||||
configuration = get_configuration()
|
||||
return val_name in configuration
|
||||
|
||||
|
||||
def get_template_path(relative_path):
|
||||
"""
|
||||
Returns a path (string) to a Mako template, which can either be in
|
||||
|
||||
@@ -6,6 +6,8 @@ A microsite enables the following features:
|
||||
2) Present a landing page with a listing of courses that are specific to the 'brand'
|
||||
3) Ability to swap out some branding elements in the website
|
||||
"""
|
||||
|
||||
from django.conf import settings
|
||||
from microsite_configuration import microsite
|
||||
|
||||
|
||||
@@ -34,3 +36,50 @@ class MicrositeMiddleware(object):
|
||||
"""
|
||||
microsite.clear()
|
||||
return response
|
||||
|
||||
|
||||
class MicrositeSessionCookieDomainMiddleware():
|
||||
"""
|
||||
Special case middleware which should be at the very end of the MIDDLEWARE list (so that it runs first
|
||||
on the process_response chain). This middleware will define a wrapper function for the set_cookie() function
|
||||
on the HttpResponse object, if the request is running in a middleware.
|
||||
|
||||
This wrapped set_cookie will change the SESSION_COOKIE_DOMAIN setting so that the cookie can be bound to a
|
||||
fully customized URL.
|
||||
"""
|
||||
|
||||
def process_response(self, request, response):
|
||||
"""
|
||||
Standard Middleware entry point
|
||||
"""
|
||||
|
||||
# See if we are running in a Microsite *AND* we have a custom SESSION_COOKIE_DOMAIN defined
|
||||
# in configuration
|
||||
if microsite.has_override_value('SESSION_COOKIE_DOMAIN'):
|
||||
|
||||
# define wrapper function for the standard set_cookie()
|
||||
def _set_cookie_wrapper(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False):
|
||||
|
||||
# only override if we are setting the cookie name to be the one the Django Session Middleware uses
|
||||
# as defined in settings.SESSION_COOKIE_NAME
|
||||
if key == settings.SESSION_COOKIE_NAME:
|
||||
domain = microsite.get_value('SESSION_COOKIE_DOMAIN', domain)
|
||||
|
||||
# then call down into the normal Django set_cookie method
|
||||
return response.set_cookie_wrapped_func(
|
||||
key,
|
||||
value,
|
||||
max_age=max_age,
|
||||
expires=expires,
|
||||
path=path,
|
||||
domain=domain,
|
||||
secure=secure,
|
||||
httponly=httponly
|
||||
)
|
||||
|
||||
# then point the HttpResponse.set_cookie to point to the wrapper and keep
|
||||
# the original around
|
||||
response.set_cookie_wrapped_func = response.set_cookie
|
||||
response.set_cookie = _set_cookie_wrapper
|
||||
|
||||
return response
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Test Microsite middleware.
|
||||
"""
|
||||
from mock import patch
|
||||
|
||||
from django.test import TestCase
|
||||
from django.conf import settings
|
||||
from django.test.client import Client
|
||||
from django.test.utils import override_settings
|
||||
import unittest
|
||||
|
||||
|
||||
# NOTE: We set SESSION_SAVE_EVERY_REQUEST to True in order to make sure
|
||||
# Sessions are always started on every request
|
||||
@override_settings(SESSION_SAVE_EVERY_REQUEST=True)
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
class MicroSiteSessionCookieTests(TestCase):
|
||||
"""
|
||||
Tests regarding the session cookie management in the middlware for MicroSites
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
# create a test client
|
||||
self.client = Client()
|
||||
|
||||
def test_session_cookie_domain_no_microsite(self):
|
||||
"""
|
||||
Tests that non-microsite behaves according to default behavior
|
||||
"""
|
||||
|
||||
response = self.client.get('/')
|
||||
self.assertNotIn('test_microsite.localhost', str(getattr(response, 'cookies')['sessionid']))
|
||||
self.assertNotIn('Domain', str(getattr(response, 'cookies')['sessionid']))
|
||||
|
||||
def test_session_cookie_domain(self):
|
||||
"""
|
||||
Makes sure that the cookie being set in a Microsite
|
||||
is the one specially overridden in configuration,
|
||||
in this case in test.py
|
||||
"""
|
||||
|
||||
response = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
|
||||
self.assertIn('test_microsite.localhost', str(getattr(response, 'cookies')['sessionid']))
|
||||
|
||||
@patch.dict("django.conf.settings.MICROSITE_CONFIGURATION", {'test_microsite': {'SESSION_COOKIE_DOMAIN': None}})
|
||||
def test_microsite_none_cookie_domain(self):
|
||||
"""
|
||||
Tests to make sure that a Microsite that specifies None for 'SESSION_COOKIE_DOMAIN' does not
|
||||
set a domain on the session cookie
|
||||
"""
|
||||
|
||||
response = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
|
||||
self.assertNotIn('test_microsite.localhost', str(getattr(response, 'cookies')['sessionid']))
|
||||
self.assertNotIn('Domain', str(getattr(response, 'cookies')['sessionid']))
|
||||
@@ -983,6 +983,9 @@ MIDDLEWARE_CLASSES = (
|
||||
'courseware.middleware.RedirectUnenrolledMiddleware',
|
||||
|
||||
'course_wiki.middleware.WikiAccessMiddleware',
|
||||
|
||||
# This must be last
|
||||
'microsite_configuration.middleware.MicrositeSessionCookieDomainMiddleware',
|
||||
)
|
||||
|
||||
# Clickjacking protection can be enabled by setting this to 'DENY'
|
||||
|
||||
@@ -367,6 +367,7 @@ MICROSITE_CONFIGURATION = {
|
||||
"COURSE_ABOUT_VISIBILITY_PERMISSION": "see_about_page",
|
||||
"ENABLE_SHOPPING_CART": True,
|
||||
"ENABLE_PAID_COURSE_REGISTRATION": True,
|
||||
"SESSION_COOKIE_DOMAIN": "test_microsite.localhost",
|
||||
},
|
||||
"default": {
|
||||
"university": "default_university",
|
||||
|
||||
Reference in New Issue
Block a user