Commit 2faba856 by Xavier Antoviaque

Switch to models configuration to avoid needing Django settings

parent 1f76472c
......@@ -6,6 +6,8 @@ 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.
Meant to be used with https://github.com/edx/edx-platform/
### Installation
Add the following configuration variables:
......
"""
Admin site bindings for splash screen
"""
from django.contrib import admin
from config_models.admin import ConfigurationModelAdmin
from splash.models import SplashConfig
admin.site.register(SplashConfig, ConfigurationModelAdmin)
......@@ -3,9 +3,10 @@ Splash screen - Middleware
"""
import logging
from django.conf import settings
from django.shortcuts import redirect
from models import SplashConfig
log = logging.getLogger(__name__)
......@@ -22,14 +23,15 @@ class SplashMiddleware(object):
"""
Determine if the user needs to be redirected
"""
if not settings.FEATURES.get('ENABLE_SPLASH_SCREEN'):
config = SplashConfig.current()
if not config.enabled:
return
# Some users should never be redirected
if request.user.username in settings.SPLASH_SCREEN_UNAFFECTED_USERS:
if request.user.username in config.unaffected_usernames_list:
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)
cookie_value = request.COOKIES.get(config.cookie_name)
if (cookie_value not in config.cookie_allowed_values_list and
request.build_absolute_uri() != config.redirect_url):
return redirect(config.redirect_url)
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'SplashConfig'
db.create_table('splash_splashconfig', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('change_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('changed_by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.PROTECT)),
('enabled', self.gf('django.db.models.fields.BooleanField')(default=False)),
('cookie_name', self.gf('django.db.models.fields.TextField')(default='edx_splash_screen')),
('cookie_allowed_values', self.gf('django.db.models.fields.TextField')(default='seen')),
('unaffected_usernames', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
('redirect_url', self.gf('django.db.models.fields.URLField')(default='http://edx.org', max_length=200)),
))
db.send_create_signal('splash', ['SplashConfig'])
def backwards(self, orm):
# Deleting model 'SplashConfig'
db.delete_table('splash_splashconfig')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'splash.splashconfig': {
'Meta': {'object_name': 'SplashConfig'},
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
'cookie_allowed_values': ('django.db.models.fields.TextField', [], {'default': "'seen'"}),
'cookie_name': ('django.db.models.fields.TextField', [], {'default': "'edx_splash_screen'"}),
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'redirect_url': ('django.db.models.fields.URLField', [], {'default': "'http://edx.org'", 'max_length': '200'}),
'unaffected_usernames': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'})
}
}
complete_apps = ['splash']
\ No newline at end of file
"""
Models for the splash screen application
"""
from django.db import models
from config_models.models import ConfigurationModel
class SplashConfig(ConfigurationModel):
"""
Configuration for the splash django app
"""
cookie_name = models.TextField(
default='edx_splash_screen',
help_text="The name of the cookie to check when assessing if the user needs to be redirected"
)
cookie_allowed_values = models.TextField(
default='seen',
help_text="Comma-separated list of values accepted as cookie values to prevent the redirect"
)
unaffected_usernames = models.TextField(
default='',
blank=True,
help_text="Comma-separated list of users which should never be redirected (usernames)"
)
redirect_url = models.URLField(
default='http://edx.org',
help_text="The URL the users should be redirected to when they don't have the right cookie"
)
@property
def cookie_allowed_values_list(self):
"""
`cookie_allowed_values` as a list of string values
"""
if not self.cookie_allowed_values.strip(): # pylint: disable=no-member
return []
return [val.strip() for val in self.cookie_allowed_values.split(',')] # pylint: disable=no-member
@property
def unaffected_usernames_list(self):
"""
`unaffected_usernames` as a list of username values
"""
if not self.unaffected_usernames.strip(): # pylint: disable=no-member
return []
return [name.strip() for name in self.unaffected_usernames.split(',')] # pylint: disable=no-member
#DarkLangConfig.current().released_languages_list
......@@ -2,15 +2,12 @@
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
from splash.models import SplashConfig
import logging
log = logging.getLogger(__name__)
......@@ -26,6 +23,7 @@ class SplashMiddlewareTestCase(TestCase):
"""
self.splash_middleware = SplashMiddleware()
self.request_factory = RequestFactory()
SplashConfig().save()
def build_request(self, username=None, cookies=None):
"""
......@@ -60,86 +58,110 @@ class SplashMiddlewareTestCase(TestCase):
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
"""
SplashConfig(
enabled=True,
).save()
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
"""
SplashConfig(
enabled=True,
cookie_allowed_values='ok1,ok2',
redirect_url='http://example.com'
).save()
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
"""
SplashConfig(
enabled=True,
cookie_allowed_values='ok1,ok2',
redirect_url='http://example.com'
).save()
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
"""
SplashConfig(
enabled=True,
cookie_name='othername',
).save()
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
"""
SplashConfig(
enabled=True,
cookie_name='othername',
).save()
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
"""
SplashConfig(
enabled=True,
unaffected_usernames='user1',
).save()
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
"""
SplashConfig(
enabled=True,
unaffected_usernames='user1',
).save()
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
"""
SplashConfig(
enabled=True,
redirect_url='http://testserver/somewhere'
).save()
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