Commit fa4e9e8a authored by Mark Watts's avatar Mark Watts
Browse files

Switched to a more secure default for auth

- Added settings overrides to allow tests to pass
parent ba78efde
......@@ -5,21 +5,24 @@ from django.http import HttpResponse, HttpResponseForbidden
from django.conf import settings
from base64 import b64decode
__ALL__ = ['basic_auth_required']
def basic_auth_required(realm='default'):
def _helper(func):
@wraps(func)
def _decorator(request, *args, **kwargs):
allowed = False
logging.info('request is secure? {}'.format(request.is_secure()))
if settings.ALLOW_ANONYMOUS_POST:
allowed = True
elif 'HTTP_AUTHORIZATION' in request.META:
if settings.REQUIRE_SECURE_AUTH and not request.is_secure():
return insecure_connection_response()
http_auth = request.META['HTTP_AUTHORIZATION']
authmeth, auth = http_auth.split(' ', 1)
if authmeth.lower() == 'basic':
authb = b64decode(auth.strip())
auth = authb.decode()
username, password = auth.split(':', 1)
username, password = decode_basic_auth(auth)
user = authenticate(username=username, password=password)
if user is None:
logging.info(
......@@ -29,11 +32,25 @@ def basic_auth_required(realm='default'):
return HttpResponseForbidden()
if allowed:
return func(request, *args, **kwargs)
res = HttpResponse()
res.status_code = 401
res.reason_phrase = 'Unauthorized'
res['WWW-Authenticate'] = 'Basic realm="{}"'.format(realm)
return res
if settings.REQUIRE_SECURE_AUTH and not request.is_secure():
return insecure_connection_response()
else:
res = HttpResponse()
res.status_code = 401
res.reason_phrase = 'Unauthorized'
res['WWW-Authenticate'] = 'Basic realm="{}"'.format(realm)
return res
return _decorator
return _helper
def insecure_connection_response():
return HttpResponseForbidden('Secure connection required')
def decode_basic_auth(auth):
authb = b64decode(auth.strip())
auth = authb.decode()
return auth.split(':', 1)
......@@ -70,4 +70,5 @@ COMP_EXECUTABLES = None # Which executable + revision should be checked as defa
USE_MEDIAN_BANDS = True # True to enable median bands on Timeline view
ALLOW_ANONYMOUS_POST = True # Whether anonymous users be allowed to post results
ALLOW_ANONYMOUS_POST = False # Whether anonymous users can post results
REQUIRE_SECURE_AUTH = True # Whether auth needs to be over a secure channel
......@@ -3,13 +3,14 @@ from datetime import datetime, timedelta
import copy
import json
from django.test import TestCase
from django.test import TestCase, override_settings
from django.core.urlresolvers import reverse
from codespeed.models import (Project, Benchmark, Revision, Branch, Executable,
Environment, Result, Report)
@override_settings(ALLOW_ANONYMOUS_POST=True)
class TestAddResult(TestCase):
def setUp(self):
......@@ -162,6 +163,7 @@ class TestAddResult(TestCase):
response.content.decode(), "Result data saved successfully")
@override_settings(ALLOW_ANONYMOUS_POST=True)
class TestAddJSONResults(TestCase):
def setUp(self):
......@@ -361,6 +363,7 @@ class TestTimeline(TestCase):
[u'2011/04/13 17:04:22 ', 2000.0, 1.11111, u'2', u'', u'default'])
@override_settings(ALLOW_ANONYMOUS_POST=True)
class TestReports(TestCase):
def setUp(self):
......
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