safeshield 1.2.2__tar.gz → 1.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of safeshield might be problematic. Click here for more details.
- {safeshield-1.2.2 → safeshield-1.3.2}/PKG-INFO +4 -1
- {safeshield-1.2.2 → safeshield-1.3.2}/README.md +4 -1
- {safeshield-1.2.2 → safeshield-1.3.2}/safeshield.egg-info/PKG-INFO +4 -1
- {safeshield-1.2.2 → safeshield-1.3.2}/setup.py +1 -1
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/core/validator.py +3 -3
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/array.py +6 -6
- safeshield-1.2.2/validator/rules/conditional.py → safeshield-1.3.2/validator/rules/basic.py +110 -205
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/comparison.py +12 -12
- safeshield-1.3.2/validator/rules/conditional.py +165 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/date.py +7 -7
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/files.py +5 -5
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/format.py +8 -8
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/string.py +8 -15
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/type.py +10 -3
- safeshield-1.3.2/validator/rules/utilities.py +138 -0
- safeshield-1.3.2/validator/services/rule_error_handler.py +239 -0
- safeshield-1.2.2/validator/rules/basic.py +0 -41
- safeshield-1.2.2/validator/rules/utilities.py +0 -213
- safeshield-1.2.2/validator/services/rule_error_handler.py +0 -42
- {safeshield-1.2.2 → safeshield-1.3.2}/LICENSE +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/safeshield.egg-info/SOURCES.txt +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/safeshield.egg-info/dependency_links.txt +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/safeshield.egg-info/requires.txt +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/safeshield.egg-info/top_level.txt +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/setup.cfg +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/__init__.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/core/__init__.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/database/__init__.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/database/detector.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/database/manager.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/exceptions.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/factory.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/__init__.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/rules/base.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/services/__init__.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/services/rule_conflict.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/services/rule_preparer.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/utils/__init__.py +0 -0
- {safeshield-1.2.2 → safeshield-1.3.2}/validator/utils/string.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: safeshield
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: Library for Help Validation Control
|
|
5
5
|
Home-page: https://github.com/WunsunTarniho/py-guard
|
|
6
6
|
Author: Wunsun Tarniho
|
|
@@ -58,3 +58,6 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
58
58
|
|
|
59
59
|
## v1.2.2 (2024-07-20)
|
|
60
60
|
- Fixed: Error when connect use postgres.
|
|
61
|
+
|
|
62
|
+
## v1.3.2 (2024-07-20)
|
|
63
|
+
- Refinement: Groups Inheritance Rule Class.
|
|
@@ -38,4 +38,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
38
38
|
- Fixed: Bug unique and exist rule.
|
|
39
39
|
|
|
40
40
|
## v1.2.2 (2024-07-20)
|
|
41
|
-
- Fixed: Error when connect use postgres.
|
|
41
|
+
- Fixed: Error when connect use postgres.
|
|
42
|
+
|
|
43
|
+
## v1.3.2 (2024-07-20)
|
|
44
|
+
- Refinement: Groups Inheritance Rule Class.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: safeshield
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: Library for Help Validation Control
|
|
5
5
|
Home-page: https://github.com/WunsunTarniho/py-guard
|
|
6
6
|
Author: Wunsun Tarniho
|
|
@@ -58,3 +58,6 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
58
58
|
|
|
59
59
|
## v1.2.2 (2024-07-20)
|
|
60
60
|
- Fixed: Error when connect use postgres.
|
|
61
|
+
|
|
62
|
+
## v1.3.2 (2024-07-20)
|
|
63
|
+
- Refinement: Groups Inheritance Rule Class.
|
|
@@ -221,18 +221,18 @@ class Validator:
|
|
|
221
221
|
try:
|
|
222
222
|
rule.set_validator(self)
|
|
223
223
|
|
|
224
|
-
# Format field name untuk pesan error (otomatis tangkap path aktual)
|
|
225
224
|
display_field = getattr(self, '_current_actual_path', field)
|
|
226
225
|
|
|
227
226
|
if not rule.validate(field, value, getattr(rule, 'params', [])):
|
|
228
227
|
msg = rule.message(display_field, getattr(rule, 'params', []))
|
|
229
|
-
self.error_handler.add_error(display_field, rule.rule_name, msg, value)
|
|
228
|
+
self.error_handler.add_error(display_field, rule.rule_name, getattr(rule, 'params', []), msg, value)
|
|
229
|
+
|
|
230
230
|
return False
|
|
231
231
|
else:
|
|
232
232
|
return True
|
|
233
233
|
except Exception as e:
|
|
234
234
|
display_field = getattr(self, '_current_actual_path', field)
|
|
235
|
-
self.error_handler.add_error(display_field, rule.rule_name, str(e), value)
|
|
235
|
+
self.error_handler.add_error(display_field, rule.rule_name, getattr(rule, 'params', []), str(e), value)
|
|
236
236
|
return False
|
|
237
237
|
|
|
238
238
|
def _get_nested_value(self, path: str) -> Any:
|
|
@@ -19,8 +19,8 @@ class ArrayRule(ValidationRule):
|
|
|
19
19
|
|
|
20
20
|
def message(self, field: str, params: List[str]) -> str:
|
|
21
21
|
if params:
|
|
22
|
-
return f"The
|
|
23
|
-
return f"The
|
|
22
|
+
return f"The :attribute must contain the keys: {', '.join(self._missing_keys)}."
|
|
23
|
+
return f"The :attribute must be an array."
|
|
24
24
|
|
|
25
25
|
class ContainsRule(ValidationRule):
|
|
26
26
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -44,7 +44,7 @@ class ContainsRule(ValidationRule):
|
|
|
44
44
|
return False
|
|
45
45
|
|
|
46
46
|
def message(self, field: str, params: List[str]) -> str:
|
|
47
|
-
return f"The :
|
|
47
|
+
return f"The :attribute must contain {params[0]}"
|
|
48
48
|
|
|
49
49
|
class DistinctRule(ValidationRule):
|
|
50
50
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -54,7 +54,7 @@ class DistinctRule(ValidationRule):
|
|
|
54
54
|
return len(value) == len(set(value))
|
|
55
55
|
|
|
56
56
|
def message(self, field: str, params: List[str]) -> str:
|
|
57
|
-
return f"The :
|
|
57
|
+
return f"The :attribute must contain unique values"
|
|
58
58
|
|
|
59
59
|
class InArrayRule(ValidationRule):
|
|
60
60
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -64,7 +64,7 @@ class InArrayRule(ValidationRule):
|
|
|
64
64
|
return str(value) in params
|
|
65
65
|
|
|
66
66
|
def message(self, field: str, params: List[str]) -> str:
|
|
67
|
-
return f"The :
|
|
67
|
+
return f"The :attribute must be one of: {', '.join(params)}"
|
|
68
68
|
|
|
69
69
|
class InArrayKeysRule(ValidationRule):
|
|
70
70
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -74,4 +74,4 @@ class InArrayKeysRule(ValidationRule):
|
|
|
74
74
|
return any(key in value for key in params)
|
|
75
75
|
|
|
76
76
|
def message(self, field: str, params: List[str]) -> str:
|
|
77
|
-
return f"The :
|
|
77
|
+
return f"The :attribute must contain at least one of these keys: {', '.join(params)}"
|
|
@@ -1,234 +1,123 @@
|
|
|
1
1
|
from .base import ValidationRule
|
|
2
2
|
from typing import Any, Dict, List, Optional, Set, Union, Tuple, Type
|
|
3
|
-
from enum import Enum
|
|
4
|
-
import re
|
|
5
|
-
import inspect
|
|
6
|
-
from collections.abc import Iterable
|
|
7
3
|
|
|
8
4
|
# =============================================
|
|
9
|
-
#
|
|
5
|
+
# BASIC VALIDATION RULES
|
|
10
6
|
# =============================================
|
|
11
7
|
|
|
12
|
-
class
|
|
8
|
+
class AnyOfRule(ValidationRule):
|
|
13
9
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
14
|
-
if
|
|
15
|
-
return True
|
|
16
|
-
|
|
17
|
-
conditions = list(zip(params[::2], params[1::2]))
|
|
18
|
-
|
|
19
|
-
condition_met = False
|
|
20
|
-
for other_field, expected_value in conditions:
|
|
21
|
-
if not other_field or expected_value is None:
|
|
22
|
-
continue
|
|
23
|
-
|
|
24
|
-
actual_value = self.get_field_value(other_field, '')
|
|
25
|
-
if actual_value == expected_value:
|
|
26
|
-
condition_met = True
|
|
27
|
-
break
|
|
28
|
-
|
|
29
|
-
if not condition_met:
|
|
30
|
-
return True
|
|
31
|
-
|
|
32
|
-
return not self.is_empty(value)
|
|
33
|
-
|
|
34
|
-
def message(self, field: str, params: List[str]) -> str:
|
|
35
|
-
valid_conditions = []
|
|
36
|
-
if len(params) >= 2 and len(params) % 2 == 0:
|
|
37
|
-
valid_conditions = [
|
|
38
|
-
f"{params[i]} = {params[i+1]}"
|
|
39
|
-
for i in range(0, len(params), 2)
|
|
40
|
-
if params[i] and params[i+1] is not None
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
if not valid_conditions:
|
|
44
|
-
return f"Invalid required_if rule configuration for {field}"
|
|
45
|
-
|
|
46
|
-
return f"The :name field is required when any of these are true: {', '.join(valid_conditions)}"
|
|
47
|
-
|
|
48
|
-
class RequiredAllIfRule(ValidationRule):
|
|
49
|
-
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
50
|
-
if len(params) < 2:
|
|
10
|
+
if not params:
|
|
51
11
|
return False
|
|
52
|
-
|
|
53
|
-
conditions = [(f.strip(), v.strip()) for f, v in zip(params[::2], params[1::2])]
|
|
54
|
-
|
|
55
|
-
all_conditions_met = all(
|
|
56
|
-
self.get_field_value(f) == v
|
|
57
|
-
for f, v in conditions
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
if not all_conditions_met:
|
|
61
|
-
return True
|
|
62
|
-
|
|
63
|
-
return not self.is_empty(value)
|
|
12
|
+
return any(self.get_field_value(param, param) == value for param in params)
|
|
64
13
|
|
|
65
14
|
def message(self, field: str, params: List[str]) -> str:
|
|
66
|
-
|
|
67
|
-
return f"The :name field is required when ALL conditions are met: {conditions}"
|
|
15
|
+
return f"The :attribute must be one of: {', '.join(params)}"
|
|
68
16
|
|
|
69
|
-
class
|
|
17
|
+
class BailRule(ValidationRule):
|
|
70
18
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
other_field, other_value = params[0], params[1]
|
|
75
|
-
actual_value = self.get_field_value(other_field, '')
|
|
76
|
-
|
|
77
|
-
if actual_value == other_value:
|
|
78
|
-
return True
|
|
79
|
-
|
|
80
|
-
return not self.is_empty(value)
|
|
19
|
+
self.validator._stop_on_first_failure = True
|
|
20
|
+
return True
|
|
81
21
|
|
|
82
22
|
def message(self, field: str, params: List[str]) -> str:
|
|
83
|
-
return
|
|
23
|
+
return ""
|
|
84
24
|
|
|
85
|
-
class
|
|
25
|
+
class RequiredRule(ValidationRule):
|
|
86
26
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
87
|
-
|
|
88
|
-
return False
|
|
89
|
-
|
|
90
|
-
if any(f in self.validator.data for f in params):
|
|
91
|
-
return not self.is_empty(value)
|
|
92
|
-
return True
|
|
27
|
+
return not self.is_empty(value)
|
|
93
28
|
|
|
94
29
|
def message(self, field: str, params: List[str]) -> str:
|
|
95
|
-
return f"The :
|
|
30
|
+
return f"The :attribute field is required."
|
|
96
31
|
|
|
97
|
-
class
|
|
32
|
+
class ProhibitedRule(ValidationRule):
|
|
98
33
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
99
|
-
|
|
100
|
-
return False
|
|
101
|
-
|
|
102
|
-
if all(f in self.validator.data for f in params):
|
|
103
|
-
return not self.is_empty(value)
|
|
104
|
-
return True
|
|
34
|
+
return self.is_empty(value)
|
|
105
35
|
|
|
106
36
|
def message(self, field: str, params: List[str]) -> str:
|
|
107
|
-
return
|
|
108
|
-
|
|
109
|
-
class
|
|
37
|
+
return "The :attribute field is must be empty."
|
|
38
|
+
|
|
39
|
+
class NullableRule(ValidationRule):
|
|
110
40
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
111
|
-
if not params:
|
|
112
|
-
return False
|
|
113
|
-
|
|
114
|
-
if any(f not in self.validator.data for f in params):
|
|
115
|
-
return not self.is_empty(value)
|
|
116
41
|
return True
|
|
117
42
|
|
|
118
43
|
def message(self, field: str, params: List[str]) -> str:
|
|
119
|
-
return f"The :
|
|
44
|
+
return f"The :attribute may be null."
|
|
120
45
|
|
|
121
|
-
class
|
|
46
|
+
class FilledRule(ValidationRule):
|
|
122
47
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
123
|
-
|
|
124
|
-
return False
|
|
125
|
-
|
|
126
|
-
if all(f not in self.validator.data for f in params):
|
|
127
|
-
return not self.is_empty(value)
|
|
128
|
-
return True
|
|
48
|
+
return value not in ('', None)
|
|
129
49
|
|
|
130
50
|
def message(self, field: str, params: List[str]) -> str:
|
|
131
|
-
return f"The :
|
|
51
|
+
return f"The :attribute field must have a value."
|
|
132
52
|
|
|
133
|
-
class
|
|
53
|
+
class PresentRule(ValidationRule):
|
|
134
54
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
135
|
-
|
|
136
|
-
return False
|
|
137
|
-
|
|
138
|
-
other_field, other_value = params[0], params[1]
|
|
139
|
-
actual_value = self.get_field_value(other_field, '')
|
|
140
|
-
|
|
141
|
-
if actual_value != other_value:
|
|
142
|
-
return True
|
|
143
|
-
|
|
144
|
-
return self.is_empty(value)
|
|
55
|
+
return field in self.validator.data
|
|
145
56
|
|
|
146
57
|
def message(self, field: str, params: List[str]) -> str:
|
|
147
|
-
return f"The :
|
|
148
|
-
|
|
149
|
-
class
|
|
58
|
+
return f"The :attribute field must be present."
|
|
59
|
+
|
|
60
|
+
class MissingRule(ValidationRule):
|
|
150
61
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
151
|
-
|
|
152
|
-
return False
|
|
153
|
-
|
|
154
|
-
other_field, other_value = params[0], params[1]
|
|
155
|
-
actual_value = self.get_field_value(other_field, '')
|
|
156
|
-
|
|
157
|
-
if actual_value == other_value:
|
|
158
|
-
return True
|
|
159
|
-
|
|
160
|
-
return self.is_empty(value)
|
|
62
|
+
return value is None
|
|
161
63
|
|
|
162
64
|
def message(self, field: str, params: List[str]) -> str:
|
|
163
|
-
return f"The :
|
|
164
|
-
|
|
165
|
-
class
|
|
65
|
+
return f"The :attribute field must be missing."
|
|
66
|
+
|
|
67
|
+
class ProhibitsRule(ValidationRule):
|
|
166
68
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
167
|
-
if
|
|
168
|
-
return False
|
|
169
|
-
|
|
170
|
-
other_field, other_value = params[0], params[1]
|
|
171
|
-
actual_value = self.get_field_value(other_field, '')
|
|
172
|
-
|
|
173
|
-
if actual_value != other_value:
|
|
69
|
+
if not params or value is None:
|
|
174
70
|
return True
|
|
175
|
-
|
|
176
|
-
return value not in ('', None)
|
|
71
|
+
return all(self.get_field_value(param, param) in (None, 'None') for param in params)
|
|
177
72
|
|
|
178
73
|
def message(self, field: str, params: List[str]) -> str:
|
|
179
|
-
return f"
|
|
180
|
-
|
|
181
|
-
class RegexRule(ValidationRule):
|
|
182
|
-
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
183
|
-
if not params or not isinstance(value, str):
|
|
184
|
-
return False
|
|
185
|
-
try:
|
|
186
|
-
return bool(re.fullmatch(params[0], value))
|
|
187
|
-
except re.error:
|
|
188
|
-
return False
|
|
74
|
+
return f"When :attribute is present, {', '.join(params)} must be absent."
|
|
189
75
|
|
|
190
|
-
|
|
191
|
-
return f"The :name format is invalid."
|
|
192
|
-
|
|
193
|
-
class NotRegexRule(ValidationRule):
|
|
76
|
+
class AcceptedRule(ValidationRule):
|
|
194
77
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
78
|
+
value = self.get_field_value(value, value)
|
|
79
|
+
|
|
80
|
+
if isinstance(value, str):
|
|
81
|
+
return value.lower() in ['yes', 'on', '1', 1, True, 'true', 'True']
|
|
82
|
+
if isinstance(value, int):
|
|
83
|
+
return value == 1
|
|
84
|
+
if isinstance(value, bool):
|
|
85
|
+
return value
|
|
86
|
+
return False
|
|
202
87
|
|
|
203
88
|
def message(self, field: str, params: List[str]) -> str:
|
|
204
|
-
return f"The :
|
|
89
|
+
return f"The :attribute must be accepted."
|
|
205
90
|
|
|
206
|
-
class
|
|
91
|
+
class DeclinedRule(ValidationRule):
|
|
207
92
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
93
|
+
value = self.get_field_value(value, value)
|
|
94
|
+
|
|
95
|
+
if isinstance(value, str):
|
|
96
|
+
return value.lower() in ['no', 'off', '0', 0, False, 'false', 'False']
|
|
97
|
+
if isinstance(value, int):
|
|
98
|
+
return value == 0
|
|
99
|
+
if isinstance(value, bool):
|
|
100
|
+
return not value
|
|
101
|
+
return False
|
|
102
|
+
|
|
211
103
|
def message(self, field: str, params: List[str]) -> str:
|
|
212
|
-
|
|
213
|
-
return f"The selected :name must be in : {', '.join(map(str, allowed_values))}"
|
|
104
|
+
return f"The :attribute must be declined."
|
|
214
105
|
|
|
215
|
-
class
|
|
106
|
+
class SometimesRule(ValidationRule):
|
|
216
107
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
217
|
-
|
|
218
|
-
return str(value) not in not_allowed_values
|
|
108
|
+
return True
|
|
219
109
|
|
|
220
110
|
def message(self, field: str, params: List[str]) -> str:
|
|
221
|
-
|
|
222
|
-
return f"The selected :name must be not in : {', '.join(map(str, not_allowed_values))}"
|
|
111
|
+
return ""
|
|
223
112
|
|
|
224
|
-
class
|
|
113
|
+
class ExcludeRule(ValidationRule):
|
|
225
114
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
115
|
+
self.validator._is_exclude = True
|
|
116
|
+
|
|
117
|
+
return True
|
|
118
|
+
|
|
229
119
|
def message(self, field: str, params: List[str]) -> str:
|
|
230
|
-
|
|
231
|
-
return f"The :name must be one of: {', '.join(map(str, allowed_values))}"
|
|
120
|
+
return ""
|
|
232
121
|
|
|
233
122
|
class UniqueRule(ValidationRule):
|
|
234
123
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -239,7 +128,6 @@ class UniqueRule(ValidationRule):
|
|
|
239
128
|
column = field if len(params) == 1 else params[1]
|
|
240
129
|
|
|
241
130
|
try:
|
|
242
|
-
# Optional: handle ignore case (id)
|
|
243
131
|
ignore_id = None
|
|
244
132
|
if len(params) > 2 and params[2].startswith('ignore:'):
|
|
245
133
|
ignore_field = params[2].split(':')[1]
|
|
@@ -250,7 +138,7 @@ class UniqueRule(ValidationRule):
|
|
|
250
138
|
return False
|
|
251
139
|
|
|
252
140
|
def message(self, field: str, params: List[str]) -> str:
|
|
253
|
-
return f"The :
|
|
141
|
+
return f"The :attribute has already been taken."
|
|
254
142
|
|
|
255
143
|
class ExistsRule(ValidationRule):
|
|
256
144
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -267,7 +155,7 @@ class ExistsRule(ValidationRule):
|
|
|
267
155
|
return False
|
|
268
156
|
|
|
269
157
|
def message(self, field: str, params: List[str]) -> str:
|
|
270
|
-
return f"The selected :
|
|
158
|
+
return f"The selected :attribute is invalid."
|
|
271
159
|
|
|
272
160
|
class ConfirmedRule(ValidationRule):
|
|
273
161
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -276,7 +164,7 @@ class ConfirmedRule(ValidationRule):
|
|
|
276
164
|
return value == self.get_field_value(confirmation_field, '')
|
|
277
165
|
|
|
278
166
|
def message(self, field: str, params: List[str]) -> str:
|
|
279
|
-
return f"The :
|
|
167
|
+
return f"The :attribute confirmation does not match."
|
|
280
168
|
|
|
281
169
|
class SameRule(ValidationRule):
|
|
282
170
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -285,7 +173,7 @@ class SameRule(ValidationRule):
|
|
|
285
173
|
return value == self.get_field_value(params[0])
|
|
286
174
|
|
|
287
175
|
def message(self, field: str, params: List[str]) -> str:
|
|
288
|
-
return f"The :
|
|
176
|
+
return f"The :attribute and {params[0]} must match."
|
|
289
177
|
|
|
290
178
|
class DifferentRule(ValidationRule):
|
|
291
179
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -294,39 +182,56 @@ class DifferentRule(ValidationRule):
|
|
|
294
182
|
return value != self.get_field_value(params[0])
|
|
295
183
|
|
|
296
184
|
def message(self, field: str, params: List[str]) -> str:
|
|
297
|
-
return f"The :
|
|
298
|
-
|
|
299
|
-
class
|
|
185
|
+
return f"The :attribute and {params[0]} must be different."
|
|
186
|
+
|
|
187
|
+
class RegexRule(ValidationRule):
|
|
300
188
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
301
|
-
if isinstance(value, str):
|
|
302
|
-
return
|
|
303
|
-
|
|
304
|
-
return value
|
|
305
|
-
|
|
306
|
-
return
|
|
307
|
-
return False
|
|
189
|
+
if not params or not isinstance(value, str):
|
|
190
|
+
return False
|
|
191
|
+
try:
|
|
192
|
+
return bool(re.fullmatch(params[0], value))
|
|
193
|
+
except re.error:
|
|
194
|
+
return False
|
|
308
195
|
|
|
309
196
|
def message(self, field: str, params: List[str]) -> str:
|
|
310
|
-
return f"The :
|
|
197
|
+
return f"The :attribute format is invalid."
|
|
311
198
|
|
|
312
|
-
class
|
|
199
|
+
class NotRegexRule(ValidationRule):
|
|
313
200
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
314
|
-
if isinstance(value, str):
|
|
315
|
-
return
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
201
|
+
if not params or not isinstance(value, str):
|
|
202
|
+
return True
|
|
203
|
+
print(not bool(re.search(params[0], value)))
|
|
204
|
+
try:
|
|
205
|
+
return not bool(re.search(params[0], value))
|
|
206
|
+
except re.error:
|
|
207
|
+
return True
|
|
321
208
|
|
|
322
209
|
def message(self, field: str, params: List[str]) -> str:
|
|
323
|
-
return f"The :
|
|
210
|
+
return f"The :attribute format is invalid."
|
|
324
211
|
|
|
212
|
+
class InRule(ValidationRule):
|
|
213
|
+
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
214
|
+
allowed_values = self._parse_option_values(field, params)
|
|
215
|
+
return (str(value) in allowed_values or value in allowed_values)
|
|
325
216
|
|
|
326
|
-
|
|
217
|
+
def message(self, field: str, params: List[str]) -> str:
|
|
218
|
+
allowed_values = self._parse_option_values(field, params)
|
|
219
|
+
return f"The selected :attribute must be in : {', '.join(map(str, allowed_values))}"
|
|
220
|
+
|
|
221
|
+
class NotInRule(ValidationRule):
|
|
327
222
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
328
|
-
self.
|
|
329
|
-
return
|
|
223
|
+
not_allowed_values = self._parse_option_values(field, params)
|
|
224
|
+
return str(value) not in not_allowed_values
|
|
330
225
|
|
|
331
226
|
def message(self, field: str, params: List[str]) -> str:
|
|
332
|
-
|
|
227
|
+
not_allowed_values = self._parse_option_values(field, params)
|
|
228
|
+
return f"The selected :attribute must be not in : {', '.join(map(str, not_allowed_values))}"
|
|
229
|
+
|
|
230
|
+
class EnumRule(ValidationRule):
|
|
231
|
+
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
232
|
+
allowed_values = self._parse_option_values(field, params)
|
|
233
|
+
return (str(value) in allowed_values or value in allowed_values)
|
|
234
|
+
|
|
235
|
+
def message(self, field: str, params: List[str]) -> str:
|
|
236
|
+
allowed_values = self._parse_option_values(field, params)
|
|
237
|
+
return f"The :attribute must be one of: {', '.join(map(str, allowed_values))}"
|
|
@@ -27,7 +27,7 @@ class MinRule(ValidationRule):
|
|
|
27
27
|
return False
|
|
28
28
|
|
|
29
29
|
def message(self, field: str, params: List[str]) -> str:
|
|
30
|
-
return f"The :
|
|
30
|
+
return f"The :attribute must be at least {params[0]}."
|
|
31
31
|
|
|
32
32
|
class MaxRule(ValidationRule):
|
|
33
33
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -85,13 +85,13 @@ class MaxRule(ValidationRule):
|
|
|
85
85
|
def message(self, field: str, params: List[str]) -> str:
|
|
86
86
|
value = self.get_field_value(field)
|
|
87
87
|
if value is None:
|
|
88
|
-
return f"The
|
|
88
|
+
return f"The :attribute must not exceed {params[0]}"
|
|
89
89
|
|
|
90
90
|
# Check all possible file size attributes
|
|
91
91
|
file_attrs = ['content_length', 'size', 'fileno']
|
|
92
92
|
if any(hasattr(value, attr) for attr in file_attrs):
|
|
93
|
-
return f"File
|
|
94
|
-
return f"The
|
|
93
|
+
return f"File :attribute must not exceed {params[0]} bytes"
|
|
94
|
+
return f"The :attribute must not exceed {params[0]}"
|
|
95
95
|
|
|
96
96
|
class BetweenRule(ValidationRule):
|
|
97
97
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -136,8 +136,8 @@ class BetweenRule(ValidationRule):
|
|
|
136
136
|
def message(self, field: str, params: List[str]) -> str:
|
|
137
137
|
value = self.get_field_value(field)
|
|
138
138
|
if hasattr(value, 'content_length') or hasattr(value, 'size'):
|
|
139
|
-
return f"File
|
|
140
|
-
return f"The
|
|
139
|
+
return f"File :attribute must be between {params[0]} and {params[1]} bytes"
|
|
140
|
+
return f"The :attribute must be between {params[0]} and {params[1]}"
|
|
141
141
|
|
|
142
142
|
class SizeRule(ValidationRule):
|
|
143
143
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -182,14 +182,14 @@ class SizeRule(ValidationRule):
|
|
|
182
182
|
def message(self, field: str, params: List[str]) -> str:
|
|
183
183
|
value = self.get_field_value(field)
|
|
184
184
|
if value is None:
|
|
185
|
-
return f"The
|
|
185
|
+
return f"The :attribute must be exactly {params[0]}"
|
|
186
186
|
|
|
187
187
|
# Check for file attributes
|
|
188
188
|
file_attrs = ['content_length', 'size', 'fileno']
|
|
189
189
|
if any(hasattr(value, attr) for attr in file_attrs):
|
|
190
|
-
return f"File
|
|
190
|
+
return f"File :attribute must be exactly {params[0]} bytes"
|
|
191
191
|
|
|
192
|
-
return f"The
|
|
192
|
+
return f"The :attribute must be exactly {params[0]}"
|
|
193
193
|
|
|
194
194
|
class DigitsRule(ValidationRule):
|
|
195
195
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -204,7 +204,7 @@ class DigitsRule(ValidationRule):
|
|
|
204
204
|
return value.isdigit() and len(value) == digits
|
|
205
205
|
|
|
206
206
|
def message(self, field: str, params: List[str]) -> str:
|
|
207
|
-
return f"The :
|
|
207
|
+
return f"The :attribute must be {params[0]} digits."
|
|
208
208
|
|
|
209
209
|
class DigitsBetweenRule(ValidationRule):
|
|
210
210
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -220,7 +220,7 @@ class DigitsBetweenRule(ValidationRule):
|
|
|
220
220
|
return value.isdigit() and min_digits <= len(value) <= max_digits
|
|
221
221
|
|
|
222
222
|
def message(self, field: str, params: List[str]) -> str:
|
|
223
|
-
return f"The :
|
|
223
|
+
return f"The :attribute must be between {params[0]} and {params[1]} digits."
|
|
224
224
|
|
|
225
225
|
class MultipleOfRule(ValidationRule):
|
|
226
226
|
def validate(self, field: str, value: Any, params: List[str]) -> bool:
|
|
@@ -237,4 +237,4 @@ class MultipleOfRule(ValidationRule):
|
|
|
237
237
|
return False
|
|
238
238
|
|
|
239
239
|
def message(self, field: str, params: List[str]) -> str:
|
|
240
|
-
return f"The :
|
|
240
|
+
return f"The :attribute must be a multiple of {params[0]}."
|