From 918519f8540cca98fee96eec0f3e2f9afb2e3073 Mon Sep 17 00:00:00 2001 From: Vladislav Poluhin Date: Tue, 23 Apr 2013 14:17:55 +0800 Subject: Form for SQL validation --- debug_toolbar/forms.py | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 debug_toolbar/forms.py (limited to 'debug_toolbar/forms.py') diff --git a/debug_toolbar/forms.py b/debug_toolbar/forms.py new file mode 100644 index 0000000..d795c17 --- /dev/null +++ b/debug_toolbar/forms.py @@ -0,0 +1,92 @@ +from django import forms +from django.conf import settings +from django.core.exceptions import ValidationError +from django.utils.functional import cached_property + +try: + import json +except ImportError: + from django.utils import simplejson as json + +try: + from hashlib import sha1 +except ImportError: + from django.utils.hashcompat import sha_constructor as sha1 + +from debug_toolbar.utils.compat.db import connections + + +class SQLSelectForm(forms.Form): + """ + Validate params + + sql: urlencoded sql with positional arguments + params: JSON encoded parameter values + duration: time for SQL to execute passed in from toolbar just for redisplay + hash: the hash of (secret + sql + params) for tamper checking + """ + sql = forms.CharField() + params = forms.CharField() + alias = forms.CharField(required=False, initial='default') + duration = forms.FloatField() + hash = forms.CharField() + + def __init__(self, *args, **kwargs): + initial = kwargs.get('initial', None) + + if initial is not None: + initial['hash'] = self.make_hash(initial) + + super(SQLSelectForm, self).__init__(*args, **kwargs) + + for name in self.fields: + self.fields[name].widget = forms.HiddenInput() + + def clean_sql(self): + value = self.cleaned_data['sql'] + + if not value.lower().strip().startswith('select'): + raise ValidationError("Only 'select' queries are allowed.") + + return value + + def clean_params(self): + value = self.cleaned_data['params'] + + try: + return json.loads(value) + except ValueError: + raise ValidationError('Is not valid JSON') + + def clean_alias(self): + value = self.cleaned_data['alias'] + + if value not in connections: + raise ValidationError("Database alias '%s' not found" % value) + + return value + + def clean_hash(self): + hash = self.cleaned_data['hash'] + + if hash != self.make_hash(self.data): + raise ValidationError('Tamper alert') + + return hash + + def reformat_sql(self): + from debug_toolbar.panels.sql import reformat_sql + sql, params = self.cleaned_data['sql'], self.cleaned_data['params'] + return reformat_sql(self.cursor.db.ops.last_executed_query(self.cursor, sql, params)) + + def make_hash(self, data): + params = settings.SECRET_KEY + data['sql'] + data['params'] + return sha1(params).hexdigest() + + @property + def connection(self): + return connections[self.cleaned_data['alias']] + + @cached_property + def cursor(self): + return self.connection.cursor() -- cgit v1.2.3 From 3d0467d9a4394c4b994a802e6e861ff2562dbb2b Mon Sep 17 00:00:00 2001 From: Vladislav Poluhin Date: Wed, 24 Apr 2013 11:14:34 +0800 Subject: Got rid of the circular imports --- debug_toolbar/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'debug_toolbar/forms.py') diff --git a/debug_toolbar/forms.py b/debug_toolbar/forms.py index d795c17..5955bfc 100644 --- a/debug_toolbar/forms.py +++ b/debug_toolbar/forms.py @@ -2,6 +2,7 @@ from django import forms from django.conf import settings from django.core.exceptions import ValidationError from django.utils.functional import cached_property +from debug_toolbar.utils.sql import reformat_sql try: import json @@ -75,7 +76,6 @@ class SQLSelectForm(forms.Form): return hash def reformat_sql(self): - from debug_toolbar.panels.sql import reformat_sql sql, params = self.cleaned_data['sql'], self.cleaned_data['params'] return reformat_sql(self.cursor.db.ops.last_executed_query(self.cursor, sql, params)) -- cgit v1.2.3 From 702f574461693efe0ea951254e2dcce7edb9a30f Mon Sep 17 00:00:00 2001 From: Vladislav Poluhin Date: Wed, 24 Apr 2013 16:04:04 +0800 Subject: Fix tests for Django 1.3 --- debug_toolbar/forms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'debug_toolbar/forms.py') diff --git a/debug_toolbar/forms.py b/debug_toolbar/forms.py index 5955bfc..9793f5e 100644 --- a/debug_toolbar/forms.py +++ b/debug_toolbar/forms.py @@ -1,7 +1,8 @@ from django import forms from django.conf import settings from django.core.exceptions import ValidationError -from django.utils.functional import cached_property + +from debug_toolbar.utils.functional import cached_property from debug_toolbar.utils.sql import reformat_sql try: -- cgit v1.2.3