Commit 1f76472c by Xavier Antoviaque

Initial commit - Add ability to redirect to a splash screen URL

Checks for the presence of a cookie with specific values when activated,
and redirect the user to a configurable URL when it is not found, or not
with an accepted value.

To be used to display a splash screen to users upon the first visit.
It's the responsability of the splash page at the redirected URL to set
the proper cookie value before sending users back to the LMS.
parents
*.pyc
*~
Splash screen middleware for Django apps
========================================
Checks incoming requests, to redirect users to a configured splash screen URL
if they don't have the proper cookie set. This can be used to display a small
marketing landing page, protect an alpha website from the public eye, make an
announcement, etc.
### Installation
Add the following configuration variables:
```python
############################### Splash screen ####################################
SPLASH_SCREEN_COOKIE_NAME = 'edx_splash_screen'
# The user cookie value must match one of the values to not be redirected to the
# splash screen URL
SPLASH_SCREEN_COOKIE_ALLOWED_VALUES = ['seen']
# Users which should never be redirected (usernames)
SPLASH_SCREEN_UNAFFECTED_USERS = []
# The URL the users should be redirected to when they don't have the right cookie
SPLASH_SCREEN_REDIRECT_URL = 'http://edx.org'
```
Add the middleware to the configuration:
```python
MIDDLEWARE_CLASSES = (
...
'splash.middleware.SplashMiddleware',
)
```
And to the `INSTALLED_APPS`:
```python
INSTALLED_APPS = (
...
# Splash screen
'splash',
)
```
# -*- coding: utf-8 -*-
#
# Imports ###########################################################
from setuptools import setup
# Main ##############################################################
setup(
name='django-splash',
version='0.1',
description='Splash screen middleware for Django apps',
packages=['splash'],
)
"""
Splash screen - Middleware
"""
import logging
from django.conf import settings
from django.shortcuts import redirect
log = logging.getLogger(__name__)
class SplashMiddleware(object):
"""
Checks incoming requests, to redirect users to a configured splash screen URL
if they don't have the proper cookie set
This can be used to display a small marketing landing page, protect an
alpha website from the public eye, make an announcement, etc.
"""
def process_request(self, request):
"""
Determine if the user needs to be redirected
"""
if not settings.FEATURES.get('ENABLE_SPLASH_SCREEN'):
return
# Some users should never be redirected
if request.user.username in settings.SPLASH_SCREEN_UNAFFECTED_USERS:
return
cookie_value = request.COOKIES.get(settings.SPLASH_SCREEN_COOKIE_NAME)
if cookie_value not in settings.SPLASH_SCREEN_COOKIE_ALLOWED_VALUES \
and request.build_absolute_uri() != settings.SPLASH_SCREEN_REDIRECT_URL:
return redirect(settings.SPLASH_SCREEN_REDIRECT_URL)
"""
Splash - Tests
"""
from mock import patch
from django.conf import settings
from django.contrib.auth.models import AnonymousUser, User
from django.test import TestCase
from django.test.client import RequestFactory
from django.test.utils import override_settings
from splash.middleware import SplashMiddleware
import logging
log = logging.getLogger(__name__)
class SplashMiddlewareTestCase(TestCase):
"""
Tests for the splash screen app middleware
"""
def setUp(self):
"""
Init
"""
self.splash_middleware = SplashMiddleware()
self.request_factory = RequestFactory()
def build_request(self, username=None, cookies=None):
"""
Builds a new request, associated with a user (anonymous by default)
"""
request = self.request_factory.get('/somewhere')
if username is None:
request.user = AnonymousUser()
else:
request.user = User.objects.create_user(username, 'test@example.com', username)
if cookies is not None:
request.COOKIES = cookies
return request
def assert_redirect(self, response, redirect_url):
"""
Check that the response redirects to `redirect_url`, without requiring client
interface on the response object
"""
self.assertTrue(response)
self.assertEquals(response.status_code, 302)
self.assertEquals(response['Location'], redirect_url)
def test_feature_disabled(self):
"""
No redirect when the feature is disabled
"""
request = self.build_request()
response = self.splash_middleware.process_request(request)
self.assertEquals(response, None)
@patch.dict(settings.FEATURES, {'ENABLE_SPLASH_SCREEN': True})
def test_no_cookie(self):
"""
No cookie present should redirect
"""
request = self.build_request()
response = self.splash_middleware.process_request(request)
self.assert_redirect(response, 'http://edx.org')
@patch.dict(settings.FEATURES, {'ENABLE_SPLASH_SCREEN': True})
@override_settings(SPLASH_SCREEN_COOKIE_ALLOWED_VALUES=['ok1', 'ok2'])
@override_settings(SPLASH_SCREEN_REDIRECT_URL='http://example.com')
def test_wrong_cookie(self):
"""
A cookie value different from the allowed ones should redirect
"""
request = self.build_request(cookies={'edx_splash_screen': 'not ok'})
response = self.splash_middleware.process_request(request)
self.assert_redirect(response, 'http://example.com')
@patch.dict(settings.FEATURES, {'ENABLE_SPLASH_SCREEN': True})
@override_settings(SPLASH_SCREEN_COOKIE_ALLOWED_VALUES=['ok1', 'ok2'])
@override_settings(SPLASH_SCREEN_REDIRECT_URL='http://example.com')
def test_right_cookie(self):
"""
A cookie value corresponding to one of the allowed ones should not redirect
"""
request = self.build_request(cookies={'edx_splash_screen': 'ok2'})
response = self.splash_middleware.process_request(request)
self.assertEquals(response, None)
@patch.dict(settings.FEATURES, {'ENABLE_SPLASH_SCREEN': True})
@override_settings(SPLASH_SCREEN_COOKIE_NAME='othername')
def test_wrong_cookie_different_cookie_name(self):
"""
Different cookie name
A cookie value different from the allowed ones should redirect
"""
request = self.build_request(cookies={'othername': 'not ok'})
response = self.splash_middleware.process_request(request)
self.assert_redirect(response, 'http://edx.org')
@patch.dict(settings.FEATURES, {'ENABLE_SPLASH_SCREEN': True})
@override_settings(SPLASH_SCREEN_COOKIE_NAME='othername')
def test_right_cookie_different_cookie_name(self):
"""
Different cookie name
A cookie value corresponding to one of the allowed ones should not redirect
"""
request = self.build_request(cookies={'othername': 'seen'})
response = self.splash_middleware.process_request(request)
self.assertEquals(response, None)
@patch.dict(settings.FEATURES, {'ENABLE_SPLASH_SCREEN': True})
@override_settings(SPLASH_SCREEN_UNAFFECTED_USERS=['user1'])
def test_not_unaffected_user(self):
"""
Setting unaffected users should still redirect other users
"""
request = self.build_request(username='user2')
response = self.splash_middleware.process_request(request)
self.assert_redirect(response, 'http://edx.org')
@patch.dict(settings.FEATURES, {'ENABLE_SPLASH_SCREEN': True})
@override_settings(SPLASH_SCREEN_UNAFFECTED_USERS=['user1'])
def test_unaffected_user(self):
"""
Unaffected users should never be redirected
"""
request = self.build_request(username='user1')
response = self.splash_middleware.process_request(request)
self.assertEquals(response, None)
@patch.dict(settings.FEATURES, {'ENABLE_SPLASH_SCREEN': True})
@override_settings(SPLASH_SCREEN_REDIRECT_URL='http://testserver/somewhere')
def test_redirect_to_current_url(self):
"""
When the URL of the redirection is the same as the current URL,
we shouldn't be redirected
"""
request = self.build_request()
response = self.splash_middleware.process_request(request)
self.assertEquals(response, None)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment