-
Notifications
You must be signed in to change notification settings - Fork 367
Expand file tree
/
Copy pathforms.py
More file actions
68 lines (49 loc) · 1.99 KB
/
forms.py
File metadata and controls
68 lines (49 loc) · 1.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from django.forms import ModelForm, Field, ValidationError, BooleanField
from django.forms.widgets import CheckboxInput
from explorer.models import Query, MSG_FAILED_BLACKLIST
from django.db import DatabaseError
import logging
import re
def _(x): return x
logger = logging.getLogger(__name__)
class SqlField(Field):
def validate(self, value):
"""
Ensure that the SQL passes the blacklist and executes. Execution check is skipped if params are present.
:param value: The SQL for this Query model.
"""
super().validate(value)
query = Query(sql=value)
passes_blacklist, failing_words = query.passes_blacklist()
error = MSG_FAILED_BLACKLIST % ', '.join(
failing_words) if not passes_blacklist else None
if not error and not query.available_params():
try:
query.execute_query_only()
except DatabaseError as e:
logger.info("error executing query: %s", e)
if (re.search("permission denied for table", str(e))):
error = None
else:
error = e
if error:
raise ValidationError(
_(error),
code="InvalidSql"
)
class QueryForm(ModelForm):
sql = SqlField()
snapshot = BooleanField(widget=CheckboxInput, required=False)
def clean(self):
if self.instance and self.data.get('created_by_user', None):
self.cleaned_data['created_by_user'] = self.instance.created_by_user
return super(QueryForm, self).clean()
@property
def created_by_user_email(self):
return self.instance.created_by_user.email if self.instance.created_by_user else '--'
@property
def created_by_user_id(self):
return self.instance.created_by_user.id if self.instance.created_by_user else ''
class Meta:
model = Query
fields = ['title', 'sql', 'description', 'created_by_user', 'snapshot']