Skip to content

Commit

Permalink
Merge pull request #35 from danpalmer/master
Browse files Browse the repository at this point in the history
Full support for Django 1.4, 1.6 and 1.7.
  • Loading branch information
funkaoshi committed Jan 7, 2015
2 parents 468ea9a + 8ce0cab commit 6c08299
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 31 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@

# ignore setup.py build dir
build/

# ignore sphinx built documentation
_build/

# ignore tox files
.tox/
1 change: 1 addition & 0 deletions CONTRIBUTERS → CONTRIBUTORS
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Contributers in alphabetical order.

Dan Palmer - https://github.com/danpalmer
Jedediah Smith - https://github.com/jedediah
Jeff Bain - https://github.com/JeffBain
Pawel Krawczyk - https://github.com/kravietz
Expand Down
4 changes: 2 additions & 2 deletions conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@

# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['_build']
exclude_patterns = ['_build/*', '.tox/*']

# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
Expand Down Expand Up @@ -121,7 +121,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = []

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
Expand Down
5 changes: 3 additions & 2 deletions security/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ def process_response(self, request, response):
class ContentSecurityPolicyMiddleware:
"""
.. _ContentSecurityPolicyMiddleware:
Adds Content Security Policy (CSP) header to HTTP response.
CSP provides fine grained instructions to the browser on
location of allowed resources loaded by the page, thus mitigating
Expand Down Expand Up @@ -726,7 +727,7 @@ def load_setting(self, setting, value):
def process_request(self, request):
if not hasattr(request, 'user'):
raise ImproperlyConfigured("The Login Required middleware"
"requires authentication middleware to be installed.")
" requires authentication middleware to be installed.")
if request.user.is_authenticated() and not request.user.is_active:
logout(request)
if not request.user.is_authenticated():
Expand All @@ -741,7 +742,7 @@ def process_request(self, request):
if request.is_ajax():
response = {"login_url": login_url}
return HttpResponse(json.dumps(response), status=401,
mimetype="application/json")
content_type="application/json")
else:
if next_url:
login_url = login_url + '?next=' + next_url
Expand Down
1 change: 1 addition & 0 deletions security/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def check_ajax(request, *args, **kwargs):
def csp_report(request, csp_save=False, csp_log=True):
"""
.. _csp_report:
Collect Content Security Policy reports from browsers. This view has
two optional keyword arguments:
Expand Down
20 changes: 17 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
# Copyright (c) 2011, SD Elements. See LICENSE.txt for details.

import os
from distutils.core import setup
import sys
import subprocess
from distutils.core import setup, Command

f = open(os.path.join(os.path.dirname(__file__), 'README.md'))
readme = f.read()
f.close()

class Test(Command):
user_options = []
def initialize_options(self):
pass

def finalize_options(self):
pass

def run(self):
errno = subprocess.call([sys.executable, 'testing/manage.py', 'test'])
raise SystemExit(errno)

setup(name="django-security",
description='A collection of tools to help secure a Django project.',
long_description=readme,
Expand All @@ -25,6 +39,6 @@
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Security',
],
install_requires=['django>=1.4',],
)
requires=['django (>=1.4)',],
cmdclass={'test': Test})

5 changes: 5 additions & 0 deletions testing/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
import os
import sys

path, scriptname = os.path.split(__file__)

sys.path.append(os.path.abspath(path))
sys.path.append(os.path.abspath(os.path.join(path, '..')))

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")

Expand Down
16 changes: 0 additions & 16 deletions testing/run_tests.py

This file was deleted.

31 changes: 28 additions & 3 deletions testing/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import os as _os
import django

def is_version(version):
return all(x >= y for x, y in zip(django.VERSION, version))


_PROJECT_PATH = _os.path.abspath(_os.path.dirname(__file__))
Expand Down Expand Up @@ -27,7 +31,6 @@
MEDIA_URL = ''
STATIC_ROOT = ''
STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/static/admin/'
STATICFILES_DIRS = ()
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
Expand All @@ -52,15 +55,14 @@
'security.middleware.ContentNoSniff',
'security.middleware.ContentSecurityPolicyMiddleware',
'security.middleware.StrictTransportSecurityMiddleware',
'django.middleware.transaction.TransactionMiddleware',
'security.middleware.P3PPolicyMiddleware',
'security.middleware.XssProtectMiddleware',
'security.middleware.MandatoryPasswordChangeMiddleware',
'security.middleware.NoConfidentialCachingMiddleware',
'security.auth_throttling.Middleware',
)
ROOT_URLCONF = 'testing.urls'
TEMPLATE_DIRS = (_os.path.join(_PROJECT_PATH, "templates"))
TEMPLATE_DIRS = (_os.path.join(_PROJECT_PATH, "templates"),)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
Expand All @@ -71,6 +73,11 @@
'tests'
)

if is_version((1, 6)):
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
else:
TEST_RUNNER = 'discover_runner.DiscoverRunner'

LOGIN_REDIRECT_URL="/home/"

# The tests for django.contrib.auth use certain URLs, and they'll fail if we
Expand Down Expand Up @@ -116,3 +123,21 @@

# Django 1.6 uses JSONSerializer which can't handle datetime
SESSION_SERIALIZER='django.contrib.sessions.serializers.PickleSerializer'

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'CRITICAL',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'': {
'handlers': ['console'],
'level': 'WARNING',
'propagate': True,
},
},
}
17 changes: 12 additions & 5 deletions testing/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ class LoginRequiredMiddlewareTests(TestCase):
def setUp(self):
self.login_url = reverse("django.contrib.auth.views.login")

def test_aborts_if_auth_middlware_missing(self):
middlware_classes = settings.MIDDLEWARE_CLASSES
def test_aborts_if_auth_middleware_missing(self):
middleware_classes = settings.MIDDLEWARE_CLASSES
auth_middleware = 'django.contrib.auth.middleware.AuthenticationMiddleware'
middlware_classes = [m for m in middlware_classes if m != auth_middleware]
with self.settings(MIDDLEWARE_CLASSES=middlware_classes):
middleware_classes = [m for m in middleware_classes if m != auth_middleware]
with self.settings(MIDDLEWARE_CLASSES=middleware_classes):
self.assertRaises(ImproperlyConfigured, self.client.get, '/home/')

def test_redirects_unauthenticated_request(self):
Expand Down Expand Up @@ -595,7 +595,14 @@ def test_csp_gen_1(self):

csp = ContentSecurityPolicyMiddleware()
generated = csp._csp_builder(csp_dict)
self.assertEqual(generated,expected)

# We can't assume the iteration order on the csp_dict, so we split the
# output, sort, and ensure we got all the results back, regardless of
# the order.
expected_list = sorted(expected.split(';'))
generated_list = sorted(generated.split(';'))

self.assertEqual(generated_list, expected_list)

def test_csp_gen_2(self):
csp_dict = { 'default-src' : ['self'] }
Expand Down
19 changes: 19 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[tox]
envlist = {py26,py27}-django{14,16}, py27-django17, docs

[testenv]
whitelist_externals = make
commands = python setup.py test
deps =
django-discover-runner
django14: django==1.4
django16: django==1.6
django17: django==1.7

[testenv:docs]
deps =
Sphinx
django
commands =
make clean
make html

0 comments on commit 6c08299

Please sign in to comment.