Show More
@@ -18,7 +18,14 b'' | |||||
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | import unicodedata |
|
21 | from rhodecode.lib.str_utils import convert_special_chars, safe_int, safe_bytes | |
|
22 | ||||
|
23 | ||||
|
24 | def to_bytes_preparer(value): | |||
|
25 | ||||
|
26 | if value: | |||
|
27 | value = safe_bytes(value) | |||
|
28 | return value | |||
22 |
|
29 | |||
23 |
|
30 | |||
24 | def strip_preparer(value): |
|
31 | def strip_preparer(value): | |
@@ -49,7 +56,7 b' def non_ascii_strip_preparer(value):' | |||||
49 | `ΕΌoΕw` converts into `zolw` |
|
56 | `ΕΌoΕw` converts into `zolw` | |
50 | """ |
|
57 | """ | |
51 | if value: |
|
58 | if value: | |
52 | value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') |
|
59 | value = convert_special_chars(value) | |
53 | return value |
|
60 | return value | |
54 |
|
61 | |||
55 |
|
62 | |||
@@ -85,4 +92,8 b' def unique_list_from_str_preparer(value)' | |||||
85 |
|
92 | |||
86 | if isinstance(value, str): |
|
93 | if isinstance(value, str): | |
87 | value = aslist(value, ',') |
|
94 | value = aslist(value, ',') | |
88 | return unique_list_preparer(value) No newline at end of file |
|
95 | return unique_list_preparer(value) | |
|
96 | ||||
|
97 | ||||
|
98 | def ensure_value_is_int(value): | |||
|
99 | return safe_int(value) |
@@ -22,6 +22,7 b' import os' | |||||
22 |
|
22 | |||
23 | import colander |
|
23 | import colander | |
24 |
|
24 | |||
|
25 | from rhodecode.lib.str_utils import safe_str | |||
25 | from rhodecode.translation import _ |
|
26 | from rhodecode.translation import _ | |
26 | from rhodecode.model.validation_schema import preparers |
|
27 | from rhodecode.model.validation_schema import preparers | |
27 |
|
28 | |||
@@ -34,7 +35,7 b' def nodes_to_sequence(nodes, colander_no' | |||||
34 |
|
35 | |||
35 | """ |
|
36 | """ | |
36 | if not isinstance(nodes, dict): |
|
37 | if not isinstance(nodes, dict): | |
37 |
msg = 'Nodes needs to be a dict, got { |
|
38 | msg = f'Nodes needs to be a dict, got {type(nodes)}' | |
38 | raise colander.Invalid(colander_node, msg) |
|
39 | raise colander.Invalid(colander_node, msg) | |
39 | out = [] |
|
40 | out = [] | |
40 |
|
41 | |||
@@ -51,6 +52,7 b' def nodes_to_sequence(nodes, colander_no' | |||||
51 |
|
52 | |||
52 |
|
53 | |||
53 | def sequence_to_nodes(nodes, colander_node=None): |
|
54 | def sequence_to_nodes(nodes, colander_node=None): | |
|
55 | ||||
54 | if not isinstance(nodes, list): |
|
56 | if not isinstance(nodes, list): | |
55 | msg = 'Nodes needs to be a list, got {}'.format(type(nodes)) |
|
57 | msg = 'Nodes needs to be a list, got {}'.format(type(nodes)) | |
56 | raise colander.Invalid(colander_node, msg) |
|
58 | raise colander.Invalid(colander_node, msg) | |
@@ -86,33 +88,41 b' def unique_gist_validator(node, value):' | |||||
86 | from rhodecode.model.db import Gist |
|
88 | from rhodecode.model.db import Gist | |
87 | existing = Gist.get_by_access_id(value) |
|
89 | existing = Gist.get_by_access_id(value) | |
88 | if existing: |
|
90 | if existing: | |
89 |
msg = _( |
|
91 | msg = _('Gist with name {} already exists').format(value) | |
90 | raise colander.Invalid(node, msg) |
|
92 | raise colander.Invalid(node, msg) | |
91 |
|
93 | |||
92 |
|
94 | |||
93 | def filename_validator(node, value): |
|
95 | def filename_validator(node, value): | |
94 | if value != os.path.basename(value): |
|
96 | if value != os.path.basename(value): | |
95 |
msg = _( |
|
97 | msg = _('Filename {} cannot be inside a directory').format(safe_str(value)) | |
96 | raise colander.Invalid(node, msg) |
|
98 | raise colander.Invalid(node, msg) | |
97 |
|
99 | |||
98 |
|
100 | |||
99 | class NodeSchema(colander.MappingSchema): |
|
101 | class NodeSchema(colander.MappingSchema): | |
100 | # if we perform rename this will be org filename |
|
102 | # if we perform rename this will be org filename | |
101 | filename_org = colander.SchemaNode( |
|
103 | filename_org = colander.SchemaNode( | |
102 | colander.String(), |
|
104 | colander.String(encoding='utf-8'), | |
103 | preparer=[preparers.strip_preparer, |
|
105 | preparer=[ | |
104 |
|
|
106 | preparers.strip_preparer, | |
|
107 | preparers.non_ascii_strip_preparer, | |||
|
108 | preparers.to_bytes_preparer, | |||
|
109 | ], | |||
105 | validator=filename_validator, |
|
110 | validator=filename_validator, | |
106 | missing=None) |
|
111 | missing=None) | |
107 |
|
112 | |||
108 | filename = colander.SchemaNode( |
|
113 | filename = colander.SchemaNode( | |
109 | colander.String(), |
|
114 | colander.String(encoding='utf-8'), | |
110 | preparer=[preparers.strip_preparer, |
|
115 | preparer=[ | |
111 |
|
|
116 | preparers.strip_preparer, | |
|
117 | preparers.non_ascii_strip_preparer, | |||
|
118 | preparers.to_bytes_preparer, | |||
|
119 | ], | |||
112 | validator=filename_validator) |
|
120 | validator=filename_validator) | |
113 |
|
121 | |||
114 | content = colander.SchemaNode( |
|
122 | content = colander.SchemaNode( | |
115 |
colander.String() |
|
123 | colander.String(encoding='utf-8'), | |
|
124 | preparer=[preparers.to_bytes_preparer]) | |||
|
125 | ||||
116 | mimetype = colander.SchemaNode( |
|
126 | mimetype = colander.SchemaNode( | |
117 | colander.String(), |
|
127 | colander.String(), | |
118 | missing=None) |
|
128 | missing=None) | |
@@ -164,7 +174,7 b' class GistSchema(colander.MappingSchema)' | |||||
164 |
|
174 | |||
165 | description = colander.SchemaNode( |
|
175 | description = colander.SchemaNode( | |
166 | colander.String(), |
|
176 | colander.String(), | |
167 |
missing= |
|
177 | missing='') | |
168 |
|
178 | |||
169 | lifetime = colander.SchemaNode( |
|
179 | lifetime = colander.SchemaNode( | |
170 | colander.Integer(), |
|
180 | colander.Integer(), | |
@@ -172,12 +182,13 b' class GistSchema(colander.MappingSchema)' | |||||
172 |
|
182 | |||
173 | gist_acl_level = colander.SchemaNode( |
|
183 | gist_acl_level = colander.SchemaNode( | |
174 | colander.String(), |
|
184 | colander.String(), | |
|
185 | missing=Gist.ACL_LEVEL_PRIVATE, | |||
175 | validator=colander.OneOf([Gist.ACL_LEVEL_PUBLIC, |
|
186 | validator=colander.OneOf([Gist.ACL_LEVEL_PUBLIC, | |
176 | Gist.ACL_LEVEL_PRIVATE])) |
|
187 | Gist.ACL_LEVEL_PRIVATE])) | |
177 |
|
188 | |||
178 | gist_type = colander.SchemaNode( |
|
189 | gist_type = colander.SchemaNode( | |
179 | colander.String(), |
|
190 | colander.String(), | |
180 |
missing=Gist.GIST_P |
|
191 | missing=Gist.GIST_PRIVATE, | |
181 | validator=colander.OneOf([Gist.GIST_PRIVATE, Gist.GIST_PUBLIC])) |
|
192 | validator=colander.OneOf([Gist.GIST_PRIVATE, Gist.GIST_PUBLIC])) | |
182 |
|
193 | |||
183 | nodes = Nodes() |
|
194 | nodes = Nodes() |
@@ -238,9 +238,18 b' def deferred_repo_name_validator(node, k' | |||||
238 |
|
238 | |||
239 | @colander.deferred |
|
239 | @colander.deferred | |
240 | def deferred_repo_group_validator(node, kw): |
|
240 | def deferred_repo_group_validator(node, kw): | |
241 | options = kw.get( |
|
241 | options = kw.get('repo_repo_group_options') | |
242 | 'repo_repo_group_options') |
|
242 | ||
243 | return colander.OneOf([x for x in options]) |
|
243 | def repo_group_validator(node, value): | |
|
244 | choices = [x for x in options] | |||
|
245 | err = _('Group ID: `${val}` is not one of allowed ${choices}') | |||
|
246 | ||||
|
247 | if preparers.ensure_value_is_int(value) not in choices: | |||
|
248 | choices = ', '.join(['%s' % x for x in sorted(choices)]) | |||
|
249 | err = _(err, mapping={'val': value, 'choices': choices}) | |||
|
250 | raise colander.Invalid(node, err) | |||
|
251 | ||||
|
252 | return repo_group_validator | |||
244 |
|
253 | |||
245 |
|
254 | |||
246 | @colander.deferred |
|
255 | @colander.deferred | |
@@ -395,6 +404,7 b' class RepoSettingsSchema(RepoSchema):' | |||||
395 | colander.Integer(), |
|
404 | colander.Integer(), | |
396 | validator=deferred_repo_group_validator, |
|
405 | validator=deferred_repo_group_validator, | |
397 | widget=deferred_repo_group_widget, |
|
406 | widget=deferred_repo_group_widget, | |
|
407 | preparers=[preparers.ensure_value_is_int], | |||
398 | missing='') |
|
408 | missing='') | |
399 |
|
409 | |||
400 | repo_clone_uri_change = colander.SchemaNode( |
|
410 | repo_clone_uri_change = colander.SchemaNode( |
@@ -18,16 +18,15 b'' | |||||
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | import os |
|
|||
22 | import re |
|
21 | import re | |
23 | import logging |
|
22 | import logging | |
24 |
|
23 | |||
25 |
|
||||
26 | import ipaddress |
|
24 | import ipaddress | |
27 | import colander |
|
25 | import colander | |
28 |
|
26 | |||
29 | from rhodecode.translation import _ |
|
27 | from rhodecode.translation import _ | |
30 |
from rhodecode.lib.utils2 import glob2re |
|
28 | from rhodecode.lib.utils2 import glob2re | |
|
29 | from rhodecode.lib.str_utils import safe_str | |||
31 | from rhodecode.lib.ext_json import json |
|
30 | from rhodecode.lib.ext_json import json | |
32 |
|
31 | |||
33 | log = logging.getLogger(__name__) |
|
32 | log = logging.getLogger(__name__) | |
@@ -36,9 +35,9 b' log = logging.getLogger(__name__)' | |||||
36 | def ip_addr_validator(node, value): |
|
35 | def ip_addr_validator(node, value): | |
37 | try: |
|
36 | try: | |
38 | # this raises an ValueError if address is not IpV4 or IpV6 |
|
37 | # this raises an ValueError if address is not IpV4 or IpV6 | |
39 |
ipaddress.ip_network(safe_ |
|
38 | ipaddress.ip_network(safe_str(value), strict=False) | |
40 | except ValueError: |
|
39 | except ValueError: | |
41 |
msg = _( |
|
40 | msg = _('Please enter a valid IPv4 or IpV6 address') | |
42 | raise colander.Invalid(node, msg) |
|
41 | raise colander.Invalid(node, msg) | |
43 |
|
42 | |||
44 |
|
43 | |||
@@ -49,9 +48,9 b' class IpAddrValidator(object):' | |||||
49 | def __call__(self, node, value): |
|
48 | def __call__(self, node, value): | |
50 | try: |
|
49 | try: | |
51 | # this raises an ValueError if address is not IpV4 or IpV6 |
|
50 | # this raises an ValueError if address is not IpV4 or IpV6 | |
52 |
ipaddress.ip_network(safe_ |
|
51 | ipaddress.ip_network(safe_str(value), strict=self.strict) | |
53 | except ValueError: |
|
52 | except ValueError: | |
54 |
msg = _( |
|
53 | msg = _('Please enter a valid IPv4 or IpV6 address') | |
55 | raise colander.Invalid(node, msg) |
|
54 | raise colander.Invalid(node, msg) | |
56 |
|
55 | |||
57 |
|
56 | |||
@@ -59,7 +58,7 b' def glob_validator(node, value):' | |||||
59 | try: |
|
58 | try: | |
60 | re.compile('^' + glob2re(value) + '$') |
|
59 | re.compile('^' + glob2re(value) + '$') | |
61 | except Exception: |
|
60 | except Exception: | |
62 |
msg = _( |
|
61 | msg = _('Invalid glob pattern') | |
63 | raise colander.Invalid(node, msg) |
|
62 | raise colander.Invalid(node, msg) | |
64 |
|
63 | |||
65 |
|
64 | |||
@@ -136,19 +135,21 b' class CloneUriValidator(object):' | |||||
136 | url_validator(value, self.repo_type, config) |
|
135 | url_validator(value, self.repo_type, config) | |
137 | except InvalidCloneUrl as e: |
|
136 | except InvalidCloneUrl as e: | |
138 | log.warning(e) |
|
137 | log.warning(e) | |
139 |
raise colander.Invalid(node, e |
|
138 | raise colander.Invalid(node, str(e)) | |
140 | except Exception: |
|
139 | except Exception as e: | |
141 | log.exception('Url validation failed') |
|
140 | log.exception('Url validation failed') | |
142 | msg = _(u'invalid clone url or credentials for {repo_type} repository').format( |
|
141 | reason = repr(e) | |
143 | repo_type=self.repo_type) |
|
142 | reason = reason.replace('<', '<').replace('>', '>') | |
|
143 | msg = _('invalid clone url or credentials for {repo_type} repository. Reason: {reason}')\ | |||
|
144 | .format(reason=reason, repo_type=self.repo_type) | |||
144 | raise colander.Invalid(node, msg) |
|
145 | raise colander.Invalid(node, msg) | |
145 |
|
146 | |||
146 |
|
147 | |||
147 | def json_validator(node, value): |
|
148 | def json_validator(node, value): | |
148 | try: |
|
149 | try: | |
149 | json.loads(value) |
|
150 | json.loads(value) | |
150 |
except (Exception,) |
|
151 | except (Exception,): | |
151 |
msg = _( |
|
152 | msg = _('Please enter a valid json object') | |
152 | raise colander.Invalid(node, msg) |
|
153 | raise colander.Invalid(node, msg) | |
153 |
|
154 | |||
154 |
|
155 | |||
@@ -156,5 +157,5 b' def json_validator_with_exc(node, value)' | |||||
156 | try: |
|
157 | try: | |
157 | json.loads(value) |
|
158 | json.loads(value) | |
158 | except (Exception,) as e: |
|
159 | except (Exception,) as e: | |
159 |
msg = _( |
|
160 | msg = _('Please enter a valid json object: `{}`'.format(e)) | |
160 | raise colander.Invalid(node, msg) |
|
161 | raise colander.Invalid(node, msg) |
General Comments 0
You need to be logged in to leave comments.
Login now