Commits

Luke Plant committed cb1a623

Reorganised into flatter structure, and removed csrf

Comments (0)

Files changed (19)

django/apps/__init__.py

-

django/apps/validator/__init__.py

-

django/apps/validator/models.py

-from django.db import models
-from django.contrib.auth.models import User
-
-class ValidationFailure(models.Model):
-    timestamp = models.DateTimeField("Time", default=models.LazyDate())
-    path = models.TextField("Request path")
-    method = models.CharField("HTTP method", maxlength=6)
-    request = models.TextField("Request object", default='', blank=True)
-    response = models.TextField("Response object", default='', blank=True)
-    errors = models.TextField("Errors")
-    
-    def __repr__(self):
-        return self.method + " " + self.path
-
-    def get_request_formatted(self):
-        import cPickle
-        try:
-            return repr(cPickle.loads(self.request))
-        except EOFError, UnpicklingError:
-            return None
-
-    def get_response(self):
-        import cPickle
-        try:
-            return cPickle.loads(self.response)
-        except EOFError, UnpicklingError:
-            return None
-  
-    class Meta:
-        ordering = ('-timestamp',)
-  
-    class Admin:
-        fields =  (
-            (None, {'fields': ('timestamp', 'path', 'method', 'errors')}),
-        )
-
-      
-    def do_validation(request, response):
-        """Do validation on response and log if it fails."""
-        from django.conf import settings
-        try:
-            VALIDATOR_APP_IGNORE_PATHS = settings.VALIDATOR_APP_IGNORE_PATHS
-        except Attribute:
-            VALIDATOR_APP_IGNORE_PATHS = ()
-                  
-        import tempfile
-        import cPickle
-        import os
-        import copy
-        
-        try:
-            content_type = response['Content-Type'].split(';')[0]
-            validator = settings.VALIDATOR_APP_VALIDATORS[content_type]
-        except KeyError, IndexError:
-            # no content type, or no validator for that content type
-            return
-            
-        for ignore_path in VALIDATOR_APP_IGNORE_PATHS:
-            if request.path.startswith(ignore_path):
-                return
-        
-        # first store data in temporary file
-        (tmpfilehandle, tmpfilepath) = tempfile.mkstemp()
-        os.write(tmpfilehandle, response.content)
-        os.close(tmpfilehandle)
-        
-        # Now execute validator and get result
-        (child_stdin, child_output) = os.popen4(validator + ' ' + tmpfilepath)
-        errors = child_output.read()
-        
-        # clean up
-        child_stdin.close()
-        child_output.close()
-        os.unlink(tmpfilepath)
-        
-        if len(errors) > 0:
-            failure = ValidationFailure(errors=errors)
-            failure.path = request.path
-            qs = request.META.get('QUERY_STRING','')
-            if qs is not None and len(qs) > 0:
-                failure.path += '?' + qs
-            failure.errors = errors
-
-            from django.core.handlers.modpython import ModPythonRequest
-            
-            if isinstance(request, ModPythonRequest):
-                # prepopulate vars
-                request._get_get()
-                request._get_post()
-                request._get_cookies()
-                request._get_files()
-                request._get_meta()
-                request._get_request()
-                request._get_raw_post_data()
-                u = request.user
-                mp = request._req
-                del request._req # get rid of mp_request
-                try:
-                    req = copy.deepcopy(request)
-                except Exception, e:
-                    req = "Couldn't stash a copy of the request: %s" % str(e)
-                request._req = mp # restore mp_request
-            else:
-                try:
-                    req = copy.deepcopy(request)
-                    # remove the stuff we can't serialize
-                    del req.META['wsgi.errors']
-                    del req.META['wsgi.file_wrapper']
-                    del req.META['wsgi.input']
-                except Exception, e:
-                    # TODO - work out why this happens
-                    req = "Couldn't stash a copy of the request: %s" % str(e)
-            
-            failure.request = cPickle.dumps(req)
-            failure.response = cPickle.dumps(response)
-            failure.method = request.META['REQUEST_METHOD']
-            failure.save()
-    do_validation = staticmethod(do_validation)    

django/apps/validator/templates/validator/base.html

-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<title>Validation status</title>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<style type="text/css">
-
-body {
-	margin: 0px 20px;
-	padding: 0px;
-}
-
-h1
-{
-	text-align: center;
-	font-size: 1.5em;
-	margin: 0px -20px;
-	padding: 10px 0px;
-	background-color: #e8e8ff;
-	border-bottom: 2px solid #8080a0;
-}
-
-h2
-{
-	margin-left: -10px;
-	font-size: 1.2em;
-	color: #000060;
-}
-
-h3
-{
-	margin-left: -5px;
-	font-size: 1.1em;
-}
-
-td, th, table
-{
-	border-collapse: collapse;
-	border: 1px solid #8080a0;
-	padding: 2px;
-}
-
-tr
-{
-	background-color: #e8e8ff;
-}
-
-tr.alt, th
-{
-	background-color: #ffffff;
-}
-
-th, td
-{
-	vertical-align: top;
-}
-
-pre
-{
-	margin: 0px;
-}
-
-</style>
-</head>
-<body>
-<h1>Django project validation monitor</h1>
-<div id="content">
-{% block content %}
-{% endblock %}
-</div>
-</body>
-</html>

django/apps/validator/templates/validator/validationfailure_detail.html

-{% extends "validator/base.html" %}
-{% block content %}
-<a href="../">[up]</a>
-<h2>Validation failure details</h2>
-
-<form method="post" action="delete/"><div>
-<input type="submit" name="delete" value="Delete" />
-</div>
-</form>
-
-<table width="100%">
-	<tr>
-		<th scope="row">Time</th>
-		<td>{{ object.timestamp|date:"d M y h:i" }}</td>
-	</tr>
-	<tr>
-		<th scope="row">Request</th>
-		<td>{{ object.method }} {{ object.path|escape }} 
-		{% ifequal object.method 'GET' %}<a href="{{ object.path|escape }}">[go]</a>{% endifequal %}
-		</td>
-	</tr>
-	<tr>
-		<th scope="row">Errors</th>
-		<td><div><pre>{{ object.errors|escape }}</pre></div></td>
-	</tr>
-	<tr>
-		<th scope="row">Response content</th>
-		<td><div><pre>{{ object.get_response.content|linenumbers }}</pre></div></td>
-	</tr>
-	<tr>
-		<th scope="row">Original request</th>
-		<td><div class="python">{{ object.get_request_formatted|escape }}</div></td>
-	</tr>
-</table>
-{% endblock %}

django/apps/validator/templates/validator/validationfailure_list.html

-{% extends "validator/base.html" %}
-{% block content %}
-
-{% if object_list %}
-	<form method="post" action="delete/">
-	<div class="errorsfound"><p>{{ object_list|length }} page(s) with errors</p></div>
-	<div>
-	<table>
-		<tr class="header">
-			<th scope="col">Time</th>
-			<th scope="col">Request</th>
-			<th scope="col">Details</th>
-			<th scope="col">Delete</th>
-		</tr>
-		{% for failure in object_list %}
-		<tr {% if forloop.counter|divisibleby:"2" %}class="alt"{% endif %}>
-			<td>{{ failure.timestamp|date:"d M Y h:i" }}</td>
-			<td><span class="method">{{ failure.method }}</span> <span class="path">{{ failure.path|escape }}</span></td>
-			<td><a href="{{failure.id}}/">Details</a></td>
-			<td><input type="checkbox" name="deleteitem{{ failure.id }}" /></td>
-		</tr>
-		{% endfor %}
-	</table>
-	<br/>
-	<input type="submit" name="deleteselected" value="Delete selected" />
-	<input type="submit" name="deleteall" value="Delete all" />
-	</div></form>
-{% else %}
-	<div class="noerrorsfound"><p>No errors found.</p></div>
-{% endif %}
-
-{% endblock %}

django/apps/validator/urls.py

-from django.conf.urls.defaults import *
-from lukeplant_me_uk.django.apps.validator.models import ValidationFailure
-
-info_dict = {
-    'queryset': ValidationFailure.objects.all(),
-}
-
-urlpatterns = patterns('',
-    (r'^$', 
-        'django.views.generic.list_detail.object_list', 
-        dict(info_dict, allow_empty=True)),
-    (r'^(?P<object_id>\d+)/$', 
-        'django.views.generic.list_detail.object_detail',
-        info_dict),
-    (r'^(?P<object_id>\d+)/delete/$', 
-        'lukeplant_me_uk.django.apps.validator.views.delete'),
-    (r'^delete/$', 
-        'lukeplant_me_uk.django.apps.validator.views.bulkdelete'),
-)

django/apps/validator/views.py

-from lukeplant_me_uk.django.apps.validator.models import ValidationFailure
-from django.http import HttpResponseRedirect
-
-def bulkdelete(request):
-    if request.POST:
-        postkeys = request.POST.keys()
-        if 'deleteall' in postkeys:
-            ValidationFailure.objects.all().delete()
-        elif 'deleteselected' in postkeys:
-            for k in postkeys:
-                if k.startswith('deleteitem'):
-                    k = k[len('deleteitem'):]
-                    try:
-                        vf = ValidationFailure.objects.get(id=k)
-                        vf.delete()
-                    except ValidationFailure.DoesNotExist:
-                        pass
-            
-    return HttpResponseRedirect("../")
-    
-def delete(request, object_id):
-    if request.POST:
-        try:
-            vf = ValidationFailure.objects.get(id=object_id)
-            vf.delete()
-        except ValidationFailure.DoesNotExist:
-            pass
-    return HttpResponseRedirect("../../")
-        

django/middleware/__init__.py

Empty file removed.

django/middleware/csrf.py

-from django.conf import settings
-from django.http import HttpResponseForbidden
-import md5
-import re
-
-_ERROR_MSG = "<h1>403 Forbidden</h1><p>Cross Site Request Forgery detected.  Request aborted.</p>"
-
-_POST_FORM = \
-    re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)
-    
-_HTML_TYPES = ('text/html', 'application/xhtml+xml')    
-
-def _make_token(session_id):
-    m = md5.new()
-    m.update(settings.CSRF_MIDDLEWARE_SECRET + session_id)
-    return m.hexdigest()
-    
-class CsrfMiddleware(object):
-    """Django middleware that adds protection against Cross Site
-    Request Forgeries by adding hidden form fields to POST forms and 
-    checking requests for the correct value.  
-    
-    In the list of middlewares, SessionMiddleware is required, and must come 
-    after this middleware.  CsrfMiddleWare must come after compression 
-    middleware.
-    
-    You must also create a setting, CSRF_MIDDLEWARE_SECRET,
-    which is a string that will be hashed with the session ID
-    to create an authentication token.  If a session ID cookie is present, this 
-    token is added to all outgoing POST forms and is expected on all incoming 
-    POST requests that have a session ID cookie.
-    
-    If you are setting cookies directly, instead of using Django's session framework,
-    this middleware will not work.
-    
-    """
-    
-    def process_request(self, request):
-        if request.POST:
-            try:
-                session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
-                csrf_token = _make_token(session_id)
-            except KeyError:
-                # No session, no check required
-                return None
-            
-            # check incoming token
-            try:
-                request_csrf_token = request.POST['csrfmiddlewaretoken']
-            except KeyError:
-                return HttpResponseForbidden(_ERROR_MSG)
-            
-            if request_csrf_token != csrf_token:
-                return HttpResponseForbidden(_ERROR_MSG)
-                
-        return None
-        
-    def process_response(self, request, response):
-        csrf_token = None
-        try:
-            cookie = response.cookies[settings.SESSION_COOKIE_NAME]
-            csrf_token = _make_token(cookie.value)
-        except KeyError:
-            # no outgoing cookie
-            try:
-                session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
-                csrf_token = _make_token(session_id)
-            except KeyError:
-                # no incoming or outgoing cookie
-                pass
-            
-        if csrf_token is not None and \
-           response['Content-Type'].split(';')[0] in _HTML_TYPES:
-           
-            # Modify any POST forms
-            extra_field = "<div style='display:none;'>" + \
-                "<input type='hidden' name='csrfmiddlewaretoken' value='" + \
-                csrf_token + "' /></div>"
-            response.content = _POST_FORM.sub('\\1' + extra_field, response.content)
-                
-            return response
-        else:
-            return response
-        

django/middleware/validator.py

-from lukeplant_me_uk.django.apps.validator.models import ValidationFailure
-
-class ValidatorMiddleware(object):
-    def process_response(self, request, response):
-        if response.status_code == 200:
-            ValidationFailure.do_validation(request, response)
-        return response
-        

django/validator/__init__.py

+

django/validator/middleware.py

+from lukeplant_me_uk.django.apps.validator.models import ValidationFailure
+
+class ValidatorMiddleware(object):
+    def process_response(self, request, response):
+        if response.status_code == 200:
+            ValidationFailure.do_validation(request, response)
+        return response
+        

django/validator/models.py

+from django.db import models
+from django.contrib.auth.models import User
+
+class ValidationFailure(models.Model):
+    timestamp = models.DateTimeField("Time", default=models.LazyDate())
+    path = models.TextField("Request path")
+    method = models.CharField("HTTP method", maxlength=6)
+    request = models.TextField("Request object", default='', blank=True)
+    response = models.TextField("Response object", default='', blank=True)
+    errors = models.TextField("Errors")
+    
+    def __repr__(self):
+        return self.method + " " + self.path
+
+    def get_request_formatted(self):
+        import cPickle
+        try:
+            return repr(cPickle.loads(self.request))
+        except EOFError, UnpicklingError:
+            return None
+
+    def get_response(self):
+        import cPickle
+        try:
+            return cPickle.loads(self.response)
+        except EOFError, UnpicklingError:
+            return None
+  
+    class Meta:
+        ordering = ('-timestamp',)
+  
+    class Admin:
+        fields =  (
+            (None, {'fields': ('timestamp', 'path', 'method', 'errors')}),
+        )
+
+      
+    def do_validation(request, response):
+        """Do validation on response and log if it fails."""
+        from django.conf import settings
+        try:
+            VALIDATOR_APP_IGNORE_PATHS = settings.VALIDATOR_APP_IGNORE_PATHS
+        except Attribute:
+            VALIDATOR_APP_IGNORE_PATHS = ()
+                  
+        import tempfile
+        import cPickle
+        import os
+        import copy
+        
+        try:
+            content_type = response['Content-Type'].split(';')[0]
+            validator = settings.VALIDATOR_APP_VALIDATORS[content_type]
+        except KeyError, IndexError:
+            # no content type, or no validator for that content type
+            return
+            
+        for ignore_path in VALIDATOR_APP_IGNORE_PATHS:
+            if request.path.startswith(ignore_path):
+                return
+        
+        # first store data in temporary file
+        (tmpfilehandle, tmpfilepath) = tempfile.mkstemp()
+        os.write(tmpfilehandle, response.content)
+        os.close(tmpfilehandle)
+        
+        # Now execute validator and get result
+        (child_stdin, child_output) = os.popen4(validator + ' ' + tmpfilepath)
+        errors = child_output.read()
+        
+        # clean up
+        child_stdin.close()
+        child_output.close()
+        os.unlink(tmpfilepath)
+        
+        if len(errors) > 0:
+            failure = ValidationFailure(errors=errors)
+            failure.path = request.path
+            qs = request.META.get('QUERY_STRING','')
+            if qs is not None and len(qs) > 0:
+                failure.path += '?' + qs
+            failure.errors = errors
+
+            from django.core.handlers.modpython import ModPythonRequest
+            
+            if isinstance(request, ModPythonRequest):
+                # prepopulate vars
+                request._get_get()
+                request._get_post()
+                request._get_cookies()
+                request._get_files()
+                request._get_meta()
+                request._get_request()
+                request._get_raw_post_data()
+                u = request.user
+                mp = request._req
+                del request._req # get rid of mp_request
+                try:
+                    req = copy.deepcopy(request)
+                except Exception, e:
+                    req = "Couldn't stash a copy of the request: %s" % str(e)
+                request._req = mp # restore mp_request
+            else:
+                try:
+                    req = copy.deepcopy(request)
+                    # remove the stuff we can't serialize
+                    del req.META['wsgi.errors']
+                    del req.META['wsgi.file_wrapper']
+                    del req.META['wsgi.input']
+                except Exception, e:
+                    # TODO - work out why this happens
+                    req = "Couldn't stash a copy of the request: %s" % str(e)
+            
+            failure.request = cPickle.dumps(req)
+            failure.response = cPickle.dumps(response)
+            failure.method = request.META['REQUEST_METHOD']
+            failure.save()
+    do_validation = staticmethod(do_validation)    

django/validator/templates/validator/base.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<title>Validation status</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<style type="text/css">
+
+body {
+	margin: 0px 20px;
+	padding: 0px;
+}
+
+h1
+{
+	text-align: center;
+	font-size: 1.5em;
+	margin: 0px -20px;
+	padding: 10px 0px;
+	background-color: #e8e8ff;
+	border-bottom: 2px solid #8080a0;
+}
+
+h2
+{
+	margin-left: -10px;
+	font-size: 1.2em;
+	color: #000060;
+}
+
+h3
+{
+	margin-left: -5px;
+	font-size: 1.1em;
+}
+
+td, th, table
+{
+	border-collapse: collapse;
+	border: 1px solid #8080a0;
+	padding: 2px;
+}
+
+tr
+{
+	background-color: #e8e8ff;
+}
+
+tr.alt, th
+{
+	background-color: #ffffff;
+}
+
+th, td
+{
+	vertical-align: top;
+}
+
+pre
+{
+	margin: 0px;
+}
+
+</style>
+</head>
+<body>
+<h1>Django project validation monitor</h1>
+<div id="content">
+{% block content %}
+{% endblock %}
+</div>
+</body>
+</html>

django/validator/templates/validator/validationfailure_detail.html

+{% extends "validator/base.html" %}
+{% block content %}
+<a href="../">[up]</a>
+<h2>Validation failure details</h2>
+
+<form method="post" action="delete/"><div>
+<input type="submit" name="delete" value="Delete" />
+</div>
+</form>
+
+<table width="100%">
+	<tr>
+		<th scope="row">Time</th>
+		<td>{{ object.timestamp|date:"d M y h:i" }}</td>
+	</tr>
+	<tr>
+		<th scope="row">Request</th>
+		<td>{{ object.method }} {{ object.path|escape }} 
+		{% ifequal object.method 'GET' %}<a href="{{ object.path|escape }}">[go]</a>{% endifequal %}
+		</td>
+	</tr>
+	<tr>
+		<th scope="row">Errors</th>
+		<td><div><pre>{{ object.errors|escape }}</pre></div></td>
+	</tr>
+	<tr>
+		<th scope="row">Response content</th>
+		<td><div><pre>{{ object.get_response.content|linenumbers }}</pre></div></td>
+	</tr>
+	<tr>
+		<th scope="row">Original request</th>
+		<td><div class="python">{{ object.get_request_formatted|escape }}</div></td>
+	</tr>
+</table>
+{% endblock %}

django/validator/templates/validator/validationfailure_list.html

+{% extends "validator/base.html" %}
+{% block content %}
+
+{% if object_list %}
+	<form method="post" action="delete/">
+	<div class="errorsfound"><p>{{ object_list|length }} page(s) with errors</p></div>
+	<div>
+	<table>
+		<tr class="header">
+			<th scope="col">Time</th>
+			<th scope="col">Request</th>
+			<th scope="col">Details</th>
+			<th scope="col">Delete</th>
+		</tr>
+		{% for failure in object_list %}
+		<tr {% if forloop.counter|divisibleby:"2" %}class="alt"{% endif %}>
+			<td>{{ failure.timestamp|date:"d M Y h:i" }}</td>
+			<td><span class="method">{{ failure.method }}</span> <span class="path">{{ failure.path|escape }}</span></td>
+			<td><a href="{{failure.id}}/">Details</a></td>
+			<td><input type="checkbox" name="deleteitem{{ failure.id }}" /></td>
+		</tr>
+		{% endfor %}
+	</table>
+	<br/>
+	<input type="submit" name="deleteselected" value="Delete selected" />
+	<input type="submit" name="deleteall" value="Delete all" />
+	</div></form>
+{% else %}
+	<div class="noerrorsfound"><p>No errors found.</p></div>
+{% endif %}
+
+{% endblock %}

django/validator/urls.py

+from django.conf.urls.defaults import *
+from lukeplant_me_uk.django.apps.validator.models import ValidationFailure
+
+info_dict = {
+    'queryset': ValidationFailure.objects.all(),
+}
+
+urlpatterns = patterns('',
+    (r'^$', 
+        'django.views.generic.list_detail.object_list', 
+        dict(info_dict, allow_empty=True)),
+    (r'^(?P<object_id>\d+)/$', 
+        'django.views.generic.list_detail.object_detail',
+        info_dict),
+    (r'^(?P<object_id>\d+)/delete/$', 
+        'lukeplant_me_uk.django.apps.validator.views.delete'),
+    (r'^delete/$', 
+        'lukeplant_me_uk.django.apps.validator.views.bulkdelete'),
+)

django/validator/views.py

+from lukeplant_me_uk.django.apps.validator.models import ValidationFailure
+from django.http import HttpResponseRedirect
+
+def bulkdelete(request):
+    if request.POST:
+        postkeys = request.POST.keys()
+        if 'deleteall' in postkeys:
+            ValidationFailure.objects.all().delete()
+        elif 'deleteselected' in postkeys:
+            for k in postkeys:
+                if k.startswith('deleteitem'):
+                    k = k[len('deleteitem'):]
+                    try:
+                        vf = ValidationFailure.objects.get(id=k)
+                        vf.delete()
+                    except ValidationFailure.DoesNotExist:
+                        pass
+            
+    return HttpResponseRedirect("../")
+    
+def delete(request, object_id):
+    if request.POST:
+        try:
+            vf = ValidationFailure.objects.get(id=object_id)
+            vf.delete()
+        except ValidationFailure.DoesNotExist:
+            pass
+    return HttpResponseRedirect("../../")
+