Completed
Push — master ( ebb95c...951ec2 )
by Camille
01:25
created

Validator.validate_fields()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 2
c 1
b 0
f 0
rs 10
cc 1
1
import timeout_decorator
2
3
from django.db import models
4
5
from django.core.exceptions import ValidationError
6
from django.core.validators import RegexValidator
7
from jsonfield import JSONField
8
9
import re # regex
10
11
from django.core.validators import validate_email
12
13
14
def get_validator_by_name(name):
15
    """
16
    For given validator name, returns associated functions array:
17
    validator = { validate_fields: vf, validate_input: vi }
18
    Where:
19
        - vf(fields)
20
            Raises a ValidationError if given fields are not valid for this validator
21
        - vi(fields, user_input)
22
            Throws a ValidationError if given input is not valid for this validator
23
24
    Returns None if there is no validator matching that name.
25
    """
26
27
    # Validators functions
28
    def text_validate_fields(fields):
29
        # TODO: Is it safe to call re.compile with user input ? Possible infinite loops ... ?
30
        try:
31
            re.compile(fields['regex'])
32
        except re.error:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable re does not seem to be defined.
Loading history...
33
            raise ValidationError(fields['message'] + " (invalid Regex syntax)")
34
35
    # Protection against Evil Regex. Only 50ms to evaluate regex - should be enough.
36
    @timeout_decorator.timeout(0.05, use_signals=False)
37
    def regex_check_timeout(regex, error_message, input):
38
        try:
39
            RegexValidator(regex, error_message)(input)
40
        except re.error: # Should not happen ...
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable re does not seem to be defined.
Loading history...
41
            raise ValidationError("Invalid validator for this field.")
42
43
    def text_validate_input(fields, input):
44
        if (fields['regex']):
45
            try:
46
                regex_check_timeout(fields['regex'], fields['message'], input)
47
            except timeout_decorator.TimeoutError:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable timeout_decorator does not seem to be defined.
Loading history...
48
                raise ValidationError(fields['message'])
49
50
    # Validators map
51
    validators_map = {
52
        Validator.VALIDATOR_NONE: {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable Validator does not seem to be defined.
Loading history...
53
            'validate_fields':    lambda f: True,
54
            'validate_input':     lambda f,i: True,
55
        },
56
        Validator.VALIDATOR_TEXT: {
57
            'validate_fields':    text_validate_fields,
58
            'validate_input':     text_validate_input
59
        },
60
        # TODO: Register validators here
61
    }
62
63
    # Find matching validator
64
    try:
65
        return validators_map[name]
66
    except KeyError:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable KeyError does not seem to be defined.
Loading history...
67
        return None
68
69
70
def validate_validator_fields(validator, fields):
71
    v = get_validator_by_name(validator)
72
    v['validate_fields'](fields)
73
74
def are_validator_fields_valid(validator, fields):
75
    try:
76
        validate_validator_fields(validator, fields)
77
        return True
78
    except ValidationError:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable ValidationError does not seem to be defined.
Loading history...
79
        return False
80
81
def validate_validator_input(validator, validator_values, value):
82
    v = get_validator_by_name(validator)
83
    v['validate_input'](validator_values, value)
84
85
def is_validator_input_valid(validator, validator_values, value):
86
    try:
87
        validate_validator_input(validator, validator_values, value)
88
        return True
89
    except ValidationError:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable ValidationError does not seem to be defined.
Loading history...
90
        return False
91
92
class Validator(models.Model):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable models does not seem to be defined.
Loading history...
93
    class Meta:
94
        pass
95
96
    VALIDATOR_TEXT = 'text'
97
    VALIDATOR_NONE = 'none'
98
    VALIDATOR_HTML_CHOICES = (
99
        (VALIDATOR_TEXT, 'Text'),
100
        (VALIDATOR_NONE, 'None')
101
    )
102
103
    # Displayed validator name
104
    display_name    = models.CharField(max_length=255)
105
    # HTML name (<input type="html_name">)
106
    html_name       = models.CharField(max_length=255,
107
                            choices=VALIDATOR_HTML_CHOICES,
108
                            default=VALIDATOR_NONE,
109
                            primary_key=True)
110
    # Serialized JSON array (fieldName => fieldDescription)
111
    values          = JSONField()
112
113
    def __str__(self):
114
        return "Validator \"%s\" (\"%s\" with values=\"%s\")" % (self.display_name, self.html_name, self.values)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
115
116
    def validate_fields(self, fields):
117
        return validate_validator_fields(self.html_name, fields)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable fields does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
118
119
    def validate_input(self, validator_values, client_input):
120
        return validate_validator_input(self.html_name, validator_values, client_input)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable client_input does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable validator_values does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
121