##// END OF EJS Templates
disallow cloning from different URI's that http[s]/svn/git/hg
marcink -
r3482:8ee36513 beta
parent child Browse files
Show More
@@ -1,809 +1,813 b''
1 """
1 """
2 Set of generic validators
2 Set of generic validators
3 """
3 """
4 import os
4 import os
5 import re
5 import re
6 import formencode
6 import formencode
7 import logging
7 import logging
8 from collections import defaultdict
8 from collections import defaultdict
9 from pylons.i18n.translation import _
9 from pylons.i18n.translation import _
10 from webhelpers.pylonslib.secure_form import authentication_token
10 from webhelpers.pylonslib.secure_form import authentication_token
11
11
12 from formencode.validators import (
12 from formencode.validators import (
13 UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set,
13 UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set,
14 NotEmpty, IPAddress, CIDR
14 NotEmpty, IPAddress, CIDR
15 )
15 )
16 from rhodecode.lib.compat import OrderedSet
16 from rhodecode.lib.compat import OrderedSet
17 from rhodecode.lib import ipaddr
17 from rhodecode.lib import ipaddr
18 from rhodecode.lib.utils import repo_name_slug
18 from rhodecode.lib.utils import repo_name_slug
19 from rhodecode.model.db import RepoGroup, Repository, UserGroup, User,\
19 from rhodecode.model.db import RepoGroup, Repository, UserGroup, User,\
20 ChangesetStatus
20 ChangesetStatus
21 from rhodecode.lib.exceptions import LdapImportError
21 from rhodecode.lib.exceptions import LdapImportError
22 from rhodecode.config.routing import ADMIN_PREFIX
22 from rhodecode.config.routing import ADMIN_PREFIX
23 from rhodecode.lib.auth import HasReposGroupPermissionAny, HasPermissionAny
23 from rhodecode.lib.auth import HasReposGroupPermissionAny, HasPermissionAny
24
24
25 # silence warnings and pylint
25 # silence warnings and pylint
26 UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, \
26 UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, \
27 NotEmpty, IPAddress, CIDR
27 NotEmpty, IPAddress, CIDR
28
28
29 log = logging.getLogger(__name__)
29 log = logging.getLogger(__name__)
30
30
31
31
32 class UniqueList(formencode.FancyValidator):
32 class UniqueList(formencode.FancyValidator):
33 """
33 """
34 Unique List !
34 Unique List !
35 """
35 """
36 messages = dict(
36 messages = dict(
37 empty=_('Value cannot be an empty list'),
37 empty=_('Value cannot be an empty list'),
38 missing_value=_('Value cannot be an empty list'),
38 missing_value=_('Value cannot be an empty list'),
39 )
39 )
40
40
41 def _to_python(self, value, state):
41 def _to_python(self, value, state):
42 if isinstance(value, list):
42 if isinstance(value, list):
43 return value
43 return value
44 elif isinstance(value, set):
44 elif isinstance(value, set):
45 return list(value)
45 return list(value)
46 elif isinstance(value, tuple):
46 elif isinstance(value, tuple):
47 return list(value)
47 return list(value)
48 elif value is None:
48 elif value is None:
49 return []
49 return []
50 else:
50 else:
51 return [value]
51 return [value]
52
52
53 def empty_value(self, value):
53 def empty_value(self, value):
54 return []
54 return []
55
55
56
56
57 class StateObj(object):
57 class StateObj(object):
58 """
58 """
59 this is needed to translate the messages using _() in validators
59 this is needed to translate the messages using _() in validators
60 """
60 """
61 _ = staticmethod(_)
61 _ = staticmethod(_)
62
62
63
63
64 def M(self, key, state=None, **kwargs):
64 def M(self, key, state=None, **kwargs):
65 """
65 """
66 returns string from self.message based on given key,
66 returns string from self.message based on given key,
67 passed kw params are used to substitute %(named)s params inside
67 passed kw params are used to substitute %(named)s params inside
68 translated strings
68 translated strings
69
69
70 :param msg:
70 :param msg:
71 :param state:
71 :param state:
72 """
72 """
73 if state is None:
73 if state is None:
74 state = StateObj()
74 state = StateObj()
75 else:
75 else:
76 state._ = staticmethod(_)
76 state._ = staticmethod(_)
77 #inject validator into state object
77 #inject validator into state object
78 return self.message(key, state, **kwargs)
78 return self.message(key, state, **kwargs)
79
79
80
80
81 def ValidUsername(edit=False, old_data={}):
81 def ValidUsername(edit=False, old_data={}):
82 class _validator(formencode.validators.FancyValidator):
82 class _validator(formencode.validators.FancyValidator):
83 messages = {
83 messages = {
84 'username_exists': _(u'Username "%(username)s" already exists'),
84 'username_exists': _(u'Username "%(username)s" already exists'),
85 'system_invalid_username':
85 'system_invalid_username':
86 _(u'Username "%(username)s" is forbidden'),
86 _(u'Username "%(username)s" is forbidden'),
87 'invalid_username':
87 'invalid_username':
88 _(u'Username may only contain alphanumeric characters '
88 _(u'Username may only contain alphanumeric characters '
89 'underscores, periods or dashes and must begin with '
89 'underscores, periods or dashes and must begin with '
90 'alphanumeric character')
90 'alphanumeric character')
91 }
91 }
92
92
93 def validate_python(self, value, state):
93 def validate_python(self, value, state):
94 if value in ['default', 'new_user']:
94 if value in ['default', 'new_user']:
95 msg = M(self, 'system_invalid_username', state, username=value)
95 msg = M(self, 'system_invalid_username', state, username=value)
96 raise formencode.Invalid(msg, value, state)
96 raise formencode.Invalid(msg, value, state)
97 #check if user is unique
97 #check if user is unique
98 old_un = None
98 old_un = None
99 if edit:
99 if edit:
100 old_un = User.get(old_data.get('user_id')).username
100 old_un = User.get(old_data.get('user_id')).username
101
101
102 if old_un != value or not edit:
102 if old_un != value or not edit:
103 if User.get_by_username(value, case_insensitive=True):
103 if User.get_by_username(value, case_insensitive=True):
104 msg = M(self, 'username_exists', state, username=value)
104 msg = M(self, 'username_exists', state, username=value)
105 raise formencode.Invalid(msg, value, state)
105 raise formencode.Invalid(msg, value, state)
106
106
107 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]*$', value) is None:
107 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]*$', value) is None:
108 msg = M(self, 'invalid_username', state)
108 msg = M(self, 'invalid_username', state)
109 raise formencode.Invalid(msg, value, state)
109 raise formencode.Invalid(msg, value, state)
110 return _validator
110 return _validator
111
111
112
112
113 def ValidRepoUser():
113 def ValidRepoUser():
114 class _validator(formencode.validators.FancyValidator):
114 class _validator(formencode.validators.FancyValidator):
115 messages = {
115 messages = {
116 'invalid_username': _(u'Username %(username)s is not valid')
116 'invalid_username': _(u'Username %(username)s is not valid')
117 }
117 }
118
118
119 def validate_python(self, value, state):
119 def validate_python(self, value, state):
120 try:
120 try:
121 User.query().filter(User.active == True)\
121 User.query().filter(User.active == True)\
122 .filter(User.username == value).one()
122 .filter(User.username == value).one()
123 except Exception:
123 except Exception:
124 msg = M(self, 'invalid_username', state, username=value)
124 msg = M(self, 'invalid_username', state, username=value)
125 raise formencode.Invalid(msg, value, state,
125 raise formencode.Invalid(msg, value, state,
126 error_dict=dict(username=msg)
126 error_dict=dict(username=msg)
127 )
127 )
128
128
129 return _validator
129 return _validator
130
130
131
131
132 def ValidUserGroup(edit=False, old_data={}):
132 def ValidUserGroup(edit=False, old_data={}):
133 class _validator(formencode.validators.FancyValidator):
133 class _validator(formencode.validators.FancyValidator):
134 messages = {
134 messages = {
135 'invalid_group': _(u'Invalid user group name'),
135 'invalid_group': _(u'Invalid user group name'),
136 'group_exist': _(u'User group "%(usergroup)s" already exists'),
136 'group_exist': _(u'User group "%(usergroup)s" already exists'),
137 'invalid_usergroup_name':
137 'invalid_usergroup_name':
138 _(u'user group name may only contain alphanumeric '
138 _(u'user group name may only contain alphanumeric '
139 'characters underscores, periods or dashes and must begin '
139 'characters underscores, periods or dashes and must begin '
140 'with alphanumeric character')
140 'with alphanumeric character')
141 }
141 }
142
142
143 def validate_python(self, value, state):
143 def validate_python(self, value, state):
144 if value in ['default']:
144 if value in ['default']:
145 msg = M(self, 'invalid_group', state)
145 msg = M(self, 'invalid_group', state)
146 raise formencode.Invalid(msg, value, state,
146 raise formencode.Invalid(msg, value, state,
147 error_dict=dict(users_group_name=msg)
147 error_dict=dict(users_group_name=msg)
148 )
148 )
149 #check if group is unique
149 #check if group is unique
150 old_ugname = None
150 old_ugname = None
151 if edit:
151 if edit:
152 old_id = old_data.get('users_group_id')
152 old_id = old_data.get('users_group_id')
153 old_ugname = UserGroup.get(old_id).users_group_name
153 old_ugname = UserGroup.get(old_id).users_group_name
154
154
155 if old_ugname != value or not edit:
155 if old_ugname != value or not edit:
156 is_existing_group = UserGroup.get_by_group_name(value,
156 is_existing_group = UserGroup.get_by_group_name(value,
157 case_insensitive=True)
157 case_insensitive=True)
158 if is_existing_group:
158 if is_existing_group:
159 msg = M(self, 'group_exist', state, usergroup=value)
159 msg = M(self, 'group_exist', state, usergroup=value)
160 raise formencode.Invalid(msg, value, state,
160 raise formencode.Invalid(msg, value, state,
161 error_dict=dict(users_group_name=msg)
161 error_dict=dict(users_group_name=msg)
162 )
162 )
163
163
164 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
164 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
165 msg = M(self, 'invalid_usergroup_name', state)
165 msg = M(self, 'invalid_usergroup_name', state)
166 raise formencode.Invalid(msg, value, state,
166 raise formencode.Invalid(msg, value, state,
167 error_dict=dict(users_group_name=msg)
167 error_dict=dict(users_group_name=msg)
168 )
168 )
169
169
170 return _validator
170 return _validator
171
171
172
172
173 def ValidReposGroup(edit=False, old_data={}):
173 def ValidReposGroup(edit=False, old_data={}):
174 class _validator(formencode.validators.FancyValidator):
174 class _validator(formencode.validators.FancyValidator):
175 messages = {
175 messages = {
176 'group_parent_id': _(u'Cannot assign this group as parent'),
176 'group_parent_id': _(u'Cannot assign this group as parent'),
177 'group_exists': _(u'Group "%(group_name)s" already exists'),
177 'group_exists': _(u'Group "%(group_name)s" already exists'),
178 'repo_exists':
178 'repo_exists':
179 _(u'Repository with name "%(group_name)s" already exists')
179 _(u'Repository with name "%(group_name)s" already exists')
180 }
180 }
181
181
182 def validate_python(self, value, state):
182 def validate_python(self, value, state):
183 # TODO WRITE VALIDATIONS
183 # TODO WRITE VALIDATIONS
184 group_name = value.get('group_name')
184 group_name = value.get('group_name')
185 group_parent_id = value.get('group_parent_id')
185 group_parent_id = value.get('group_parent_id')
186
186
187 # slugify repo group just in case :)
187 # slugify repo group just in case :)
188 slug = repo_name_slug(group_name)
188 slug = repo_name_slug(group_name)
189
189
190 # check for parent of self
190 # check for parent of self
191 parent_of_self = lambda: (
191 parent_of_self = lambda: (
192 old_data['group_id'] == int(group_parent_id)
192 old_data['group_id'] == int(group_parent_id)
193 if group_parent_id else False
193 if group_parent_id else False
194 )
194 )
195 if edit and parent_of_self():
195 if edit and parent_of_self():
196 msg = M(self, 'group_parent_id', state)
196 msg = M(self, 'group_parent_id', state)
197 raise formencode.Invalid(msg, value, state,
197 raise formencode.Invalid(msg, value, state,
198 error_dict=dict(group_parent_id=msg)
198 error_dict=dict(group_parent_id=msg)
199 )
199 )
200
200
201 old_gname = None
201 old_gname = None
202 if edit:
202 if edit:
203 old_gname = RepoGroup.get(old_data.get('group_id')).group_name
203 old_gname = RepoGroup.get(old_data.get('group_id')).group_name
204
204
205 if old_gname != group_name or not edit:
205 if old_gname != group_name or not edit:
206
206
207 # check group
207 # check group
208 gr = RepoGroup.query()\
208 gr = RepoGroup.query()\
209 .filter(RepoGroup.group_name == slug)\
209 .filter(RepoGroup.group_name == slug)\
210 .filter(RepoGroup.group_parent_id == group_parent_id)\
210 .filter(RepoGroup.group_parent_id == group_parent_id)\
211 .scalar()
211 .scalar()
212
212
213 if gr:
213 if gr:
214 msg = M(self, 'group_exists', state, group_name=slug)
214 msg = M(self, 'group_exists', state, group_name=slug)
215 raise formencode.Invalid(msg, value, state,
215 raise formencode.Invalid(msg, value, state,
216 error_dict=dict(group_name=msg)
216 error_dict=dict(group_name=msg)
217 )
217 )
218
218
219 # check for same repo
219 # check for same repo
220 repo = Repository.query()\
220 repo = Repository.query()\
221 .filter(Repository.repo_name == slug)\
221 .filter(Repository.repo_name == slug)\
222 .scalar()
222 .scalar()
223
223
224 if repo:
224 if repo:
225 msg = M(self, 'repo_exists', state, group_name=slug)
225 msg = M(self, 'repo_exists', state, group_name=slug)
226 raise formencode.Invalid(msg, value, state,
226 raise formencode.Invalid(msg, value, state,
227 error_dict=dict(group_name=msg)
227 error_dict=dict(group_name=msg)
228 )
228 )
229
229
230 return _validator
230 return _validator
231
231
232
232
233 def ValidPassword():
233 def ValidPassword():
234 class _validator(formencode.validators.FancyValidator):
234 class _validator(formencode.validators.FancyValidator):
235 messages = {
235 messages = {
236 'invalid_password':
236 'invalid_password':
237 _(u'Invalid characters (non-ascii) in password')
237 _(u'Invalid characters (non-ascii) in password')
238 }
238 }
239
239
240 def validate_python(self, value, state):
240 def validate_python(self, value, state):
241 try:
241 try:
242 (value or '').decode('ascii')
242 (value or '').decode('ascii')
243 except UnicodeError:
243 except UnicodeError:
244 msg = M(self, 'invalid_password', state)
244 msg = M(self, 'invalid_password', state)
245 raise formencode.Invalid(msg, value, state,)
245 raise formencode.Invalid(msg, value, state,)
246 return _validator
246 return _validator
247
247
248
248
249 def ValidPasswordsMatch():
249 def ValidPasswordsMatch():
250 class _validator(formencode.validators.FancyValidator):
250 class _validator(formencode.validators.FancyValidator):
251 messages = {
251 messages = {
252 'password_mismatch': _(u'Passwords do not match'),
252 'password_mismatch': _(u'Passwords do not match'),
253 }
253 }
254
254
255 def validate_python(self, value, state):
255 def validate_python(self, value, state):
256
256
257 pass_val = value.get('password') or value.get('new_password')
257 pass_val = value.get('password') or value.get('new_password')
258 if pass_val != value['password_confirmation']:
258 if pass_val != value['password_confirmation']:
259 msg = M(self, 'password_mismatch', state)
259 msg = M(self, 'password_mismatch', state)
260 raise formencode.Invalid(msg, value, state,
260 raise formencode.Invalid(msg, value, state,
261 error_dict=dict(password_confirmation=msg)
261 error_dict=dict(password_confirmation=msg)
262 )
262 )
263 return _validator
263 return _validator
264
264
265
265
266 def ValidAuth():
266 def ValidAuth():
267 class _validator(formencode.validators.FancyValidator):
267 class _validator(formencode.validators.FancyValidator):
268 messages = {
268 messages = {
269 'invalid_password': _(u'invalid password'),
269 'invalid_password': _(u'invalid password'),
270 'invalid_username': _(u'invalid user name'),
270 'invalid_username': _(u'invalid user name'),
271 'disabled_account': _(u'Your account is disabled')
271 'disabled_account': _(u'Your account is disabled')
272 }
272 }
273
273
274 def validate_python(self, value, state):
274 def validate_python(self, value, state):
275 from rhodecode.lib.auth import authenticate
275 from rhodecode.lib.auth import authenticate
276
276
277 password = value['password']
277 password = value['password']
278 username = value['username']
278 username = value['username']
279
279
280 if not authenticate(username, password):
280 if not authenticate(username, password):
281 user = User.get_by_username(username)
281 user = User.get_by_username(username)
282 if user and user.active is False:
282 if user and user.active is False:
283 log.warning('user %s is disabled' % username)
283 log.warning('user %s is disabled' % username)
284 msg = M(self, 'disabled_account', state)
284 msg = M(self, 'disabled_account', state)
285 raise formencode.Invalid(msg, value, state,
285 raise formencode.Invalid(msg, value, state,
286 error_dict=dict(username=msg)
286 error_dict=dict(username=msg)
287 )
287 )
288 else:
288 else:
289 log.warning('user %s failed to authenticate' % username)
289 log.warning('user %s failed to authenticate' % username)
290 msg = M(self, 'invalid_username', state)
290 msg = M(self, 'invalid_username', state)
291 msg2 = M(self, 'invalid_password', state)
291 msg2 = M(self, 'invalid_password', state)
292 raise formencode.Invalid(msg, value, state,
292 raise formencode.Invalid(msg, value, state,
293 error_dict=dict(username=msg, password=msg2)
293 error_dict=dict(username=msg, password=msg2)
294 )
294 )
295 return _validator
295 return _validator
296
296
297
297
298 def ValidAuthToken():
298 def ValidAuthToken():
299 class _validator(formencode.validators.FancyValidator):
299 class _validator(formencode.validators.FancyValidator):
300 messages = {
300 messages = {
301 'invalid_token': _(u'Token mismatch')
301 'invalid_token': _(u'Token mismatch')
302 }
302 }
303
303
304 def validate_python(self, value, state):
304 def validate_python(self, value, state):
305 if value != authentication_token():
305 if value != authentication_token():
306 msg = M(self, 'invalid_token', state)
306 msg = M(self, 'invalid_token', state)
307 raise formencode.Invalid(msg, value, state)
307 raise formencode.Invalid(msg, value, state)
308 return _validator
308 return _validator
309
309
310
310
311 def ValidRepoName(edit=False, old_data={}):
311 def ValidRepoName(edit=False, old_data={}):
312 class _validator(formencode.validators.FancyValidator):
312 class _validator(formencode.validators.FancyValidator):
313 messages = {
313 messages = {
314 'invalid_repo_name':
314 'invalid_repo_name':
315 _(u'Repository name %(repo)s is disallowed'),
315 _(u'Repository name %(repo)s is disallowed'),
316 'repository_exists':
316 'repository_exists':
317 _(u'Repository named %(repo)s already exists'),
317 _(u'Repository named %(repo)s already exists'),
318 'repository_in_group_exists': _(u'Repository "%(repo)s" already '
318 'repository_in_group_exists': _(u'Repository "%(repo)s" already '
319 'exists in group "%(group)s"'),
319 'exists in group "%(group)s"'),
320 'same_group_exists': _(u'Repository group with name "%(repo)s" '
320 'same_group_exists': _(u'Repository group with name "%(repo)s" '
321 'already exists')
321 'already exists')
322 }
322 }
323
323
324 def _to_python(self, value, state):
324 def _to_python(self, value, state):
325 repo_name = repo_name_slug(value.get('repo_name', ''))
325 repo_name = repo_name_slug(value.get('repo_name', ''))
326 repo_group = value.get('repo_group')
326 repo_group = value.get('repo_group')
327 if repo_group:
327 if repo_group:
328 gr = RepoGroup.get(repo_group)
328 gr = RepoGroup.get(repo_group)
329 group_path = gr.full_path
329 group_path = gr.full_path
330 group_name = gr.group_name
330 group_name = gr.group_name
331 # value needs to be aware of group name in order to check
331 # value needs to be aware of group name in order to check
332 # db key This is an actual just the name to store in the
332 # db key This is an actual just the name to store in the
333 # database
333 # database
334 repo_name_full = group_path + RepoGroup.url_sep() + repo_name
334 repo_name_full = group_path + RepoGroup.url_sep() + repo_name
335 else:
335 else:
336 group_name = group_path = ''
336 group_name = group_path = ''
337 repo_name_full = repo_name
337 repo_name_full = repo_name
338
338
339 value['repo_name'] = repo_name
339 value['repo_name'] = repo_name
340 value['repo_name_full'] = repo_name_full
340 value['repo_name_full'] = repo_name_full
341 value['group_path'] = group_path
341 value['group_path'] = group_path
342 value['group_name'] = group_name
342 value['group_name'] = group_name
343 return value
343 return value
344
344
345 def validate_python(self, value, state):
345 def validate_python(self, value, state):
346
346
347 repo_name = value.get('repo_name')
347 repo_name = value.get('repo_name')
348 repo_name_full = value.get('repo_name_full')
348 repo_name_full = value.get('repo_name_full')
349 group_path = value.get('group_path')
349 group_path = value.get('group_path')
350 group_name = value.get('group_name')
350 group_name = value.get('group_name')
351
351
352 if repo_name in [ADMIN_PREFIX, '']:
352 if repo_name in [ADMIN_PREFIX, '']:
353 msg = M(self, 'invalid_repo_name', state, repo=repo_name)
353 msg = M(self, 'invalid_repo_name', state, repo=repo_name)
354 raise formencode.Invalid(msg, value, state,
354 raise formencode.Invalid(msg, value, state,
355 error_dict=dict(repo_name=msg)
355 error_dict=dict(repo_name=msg)
356 )
356 )
357
357
358 rename = old_data.get('repo_name') != repo_name_full
358 rename = old_data.get('repo_name') != repo_name_full
359 create = not edit
359 create = not edit
360 if rename or create:
360 if rename or create:
361
361
362 if group_path != '':
362 if group_path != '':
363 if Repository.get_by_repo_name(repo_name_full):
363 if Repository.get_by_repo_name(repo_name_full):
364 msg = M(self, 'repository_in_group_exists', state,
364 msg = M(self, 'repository_in_group_exists', state,
365 repo=repo_name, group=group_name)
365 repo=repo_name, group=group_name)
366 raise formencode.Invalid(msg, value, state,
366 raise formencode.Invalid(msg, value, state,
367 error_dict=dict(repo_name=msg)
367 error_dict=dict(repo_name=msg)
368 )
368 )
369 elif RepoGroup.get_by_group_name(repo_name_full):
369 elif RepoGroup.get_by_group_name(repo_name_full):
370 msg = M(self, 'same_group_exists', state,
370 msg = M(self, 'same_group_exists', state,
371 repo=repo_name)
371 repo=repo_name)
372 raise formencode.Invalid(msg, value, state,
372 raise formencode.Invalid(msg, value, state,
373 error_dict=dict(repo_name=msg)
373 error_dict=dict(repo_name=msg)
374 )
374 )
375
375
376 elif Repository.get_by_repo_name(repo_name_full):
376 elif Repository.get_by_repo_name(repo_name_full):
377 msg = M(self, 'repository_exists', state,
377 msg = M(self, 'repository_exists', state,
378 repo=repo_name)
378 repo=repo_name)
379 raise formencode.Invalid(msg, value, state,
379 raise formencode.Invalid(msg, value, state,
380 error_dict=dict(repo_name=msg)
380 error_dict=dict(repo_name=msg)
381 )
381 )
382 return value
382 return value
383 return _validator
383 return _validator
384
384
385
385
386 def ValidForkName(*args, **kwargs):
386 def ValidForkName(*args, **kwargs):
387 return ValidRepoName(*args, **kwargs)
387 return ValidRepoName(*args, **kwargs)
388
388
389
389
390 def SlugifyName():
390 def SlugifyName():
391 class _validator(formencode.validators.FancyValidator):
391 class _validator(formencode.validators.FancyValidator):
392
392
393 def _to_python(self, value, state):
393 def _to_python(self, value, state):
394 return repo_name_slug(value)
394 return repo_name_slug(value)
395
395
396 def validate_python(self, value, state):
396 def validate_python(self, value, state):
397 pass
397 pass
398
398
399 return _validator
399 return _validator
400
400
401
401
402 def ValidCloneUri():
402 def ValidCloneUri():
403 from rhodecode.lib.utils import make_ui
403 from rhodecode.lib.utils import make_ui
404
404
405 def url_handler(repo_type, url, ui=None):
405 def url_handler(repo_type, url, ui=None):
406 if repo_type == 'hg':
406 if repo_type == 'hg':
407 from rhodecode.lib.vcs.backends.hg.repository import MercurialRepository
407 from rhodecode.lib.vcs.backends.hg.repository import MercurialRepository
408 from mercurial.httppeer import httppeer
408 from mercurial.httppeer import httppeer
409 if url.startswith('http'):
409 if url.startswith('http'):
410 ## initially check if it's at least the proper URL
410 ## initially check if it's at least the proper URL
411 ## or does it pass basic auth
411 ## or does it pass basic auth
412 MercurialRepository._check_url(url)
412 MercurialRepository._check_url(url)
413 httppeer(ui, url)._capabilities()
413 httppeer(ui, url)._capabilities()
414 elif url.startswith('svn+http'):
414 elif url.startswith('svn+http'):
415 from hgsubversion.svnrepo import svnremoterepo
415 from hgsubversion.svnrepo import svnremoterepo
416 svnremoterepo(ui, url).capabilities
416 svnremoterepo(ui, url).capabilities
417 elif url.startswith('git+http'):
417 elif url.startswith('git+http'):
418 raise NotImplementedError()
418 raise NotImplementedError()
419 else:
420 raise Exception('clone from URI %s not allowed' % (url))
419
421
420 elif repo_type == 'git':
422 elif repo_type == 'git':
421 from rhodecode.lib.vcs.backends.git.repository import GitRepository
423 from rhodecode.lib.vcs.backends.git.repository import GitRepository
422 if url.startswith('http'):
424 if url.startswith('http'):
423 ## initially check if it's at least the proper URL
425 ## initially check if it's at least the proper URL
424 ## or does it pass basic auth
426 ## or does it pass basic auth
425 GitRepository._check_url(url)
427 GitRepository._check_url(url)
426 elif url.startswith('svn+http'):
428 elif url.startswith('svn+http'):
427 raise NotImplementedError()
429 raise NotImplementedError()
428 elif url.startswith('hg+http'):
430 elif url.startswith('hg+http'):
429 raise NotImplementedError()
431 raise NotImplementedError()
432 else:
433 raise Exception('clone from URI %s not allowed' % (url))
430
434
431 class _validator(formencode.validators.FancyValidator):
435 class _validator(formencode.validators.FancyValidator):
432 messages = {
436 messages = {
433 'clone_uri': _(u'invalid clone url'),
437 'clone_uri': _(u'invalid clone url'),
434 'invalid_clone_uri': _(u'Invalid clone url, provide a '
438 'invalid_clone_uri': _(u'Invalid clone url, provide a '
435 'valid clone http(s)/svn+http(s) url')
439 'valid clone http(s)/svn+http(s) url')
436 }
440 }
437
441
438 def validate_python(self, value, state):
442 def validate_python(self, value, state):
439 repo_type = value.get('repo_type')
443 repo_type = value.get('repo_type')
440 url = value.get('clone_uri')
444 url = value.get('clone_uri')
441
445
442 if not url:
446 if not url:
443 pass
447 pass
444 else:
448 else:
445 try:
449 try:
446 url_handler(repo_type, url, make_ui('db', clear_session=False))
450 url_handler(repo_type, url, make_ui('db', clear_session=False))
447 except Exception:
451 except Exception:
448 log.exception('Url validation failed')
452 log.exception('Url validation failed')
449 msg = M(self, 'clone_uri')
453 msg = M(self, 'clone_uri')
450 raise formencode.Invalid(msg, value, state,
454 raise formencode.Invalid(msg, value, state,
451 error_dict=dict(clone_uri=msg)
455 error_dict=dict(clone_uri=msg)
452 )
456 )
453 return _validator
457 return _validator
454
458
455
459
456 def ValidForkType(old_data={}):
460 def ValidForkType(old_data={}):
457 class _validator(formencode.validators.FancyValidator):
461 class _validator(formencode.validators.FancyValidator):
458 messages = {
462 messages = {
459 'invalid_fork_type': _(u'Fork have to be the same type as parent')
463 'invalid_fork_type': _(u'Fork have to be the same type as parent')
460 }
464 }
461
465
462 def validate_python(self, value, state):
466 def validate_python(self, value, state):
463 if old_data['repo_type'] != value:
467 if old_data['repo_type'] != value:
464 msg = M(self, 'invalid_fork_type', state)
468 msg = M(self, 'invalid_fork_type', state)
465 raise formencode.Invalid(msg, value, state,
469 raise formencode.Invalid(msg, value, state,
466 error_dict=dict(repo_type=msg)
470 error_dict=dict(repo_type=msg)
467 )
471 )
468 return _validator
472 return _validator
469
473
470
474
471 def CanWriteGroup():
475 def CanWriteGroup():
472 class _validator(formencode.validators.FancyValidator):
476 class _validator(formencode.validators.FancyValidator):
473 messages = {
477 messages = {
474 'permission_denied': _(u"You don't have permissions "
478 'permission_denied': _(u"You don't have permissions "
475 "to create repository in this group"),
479 "to create repository in this group"),
476 'permission_denied_root': _(u"no permission to create repository "
480 'permission_denied_root': _(u"no permission to create repository "
477 "in root location")
481 "in root location")
478 }
482 }
479
483
480 def _to_python(self, value, state):
484 def _to_python(self, value, state):
481 #root location
485 #root location
482 if value in [-1, "-1"]:
486 if value in [-1, "-1"]:
483 return None
487 return None
484 return value
488 return value
485
489
486 def validate_python(self, value, state):
490 def validate_python(self, value, state):
487 gr = RepoGroup.get(value)
491 gr = RepoGroup.get(value)
488 gr_name = gr.group_name if gr else None # None means ROOT location
492 gr_name = gr.group_name if gr else None # None means ROOT location
489 val = HasReposGroupPermissionAny('group.write', 'group.admin')
493 val = HasReposGroupPermissionAny('group.write', 'group.admin')
490 can_create_repos = HasPermissionAny('hg.admin', 'hg.create.repository')
494 can_create_repos = HasPermissionAny('hg.admin', 'hg.create.repository')
491 forbidden = not val(gr_name, 'can write into group validator')
495 forbidden = not val(gr_name, 'can write into group validator')
492 #parent group need to be existing
496 #parent group need to be existing
493 if gr and forbidden:
497 if gr and forbidden:
494 msg = M(self, 'permission_denied', state)
498 msg = M(self, 'permission_denied', state)
495 raise formencode.Invalid(msg, value, state,
499 raise formencode.Invalid(msg, value, state,
496 error_dict=dict(repo_type=msg)
500 error_dict=dict(repo_type=msg)
497 )
501 )
498 ## check if we can write to root location !
502 ## check if we can write to root location !
499 elif gr is None and can_create_repos() is False:
503 elif gr is None and can_create_repos() is False:
500 msg = M(self, 'permission_denied_root', state)
504 msg = M(self, 'permission_denied_root', state)
501 raise formencode.Invalid(msg, value, state,
505 raise formencode.Invalid(msg, value, state,
502 error_dict=dict(repo_type=msg)
506 error_dict=dict(repo_type=msg)
503 )
507 )
504
508
505 return _validator
509 return _validator
506
510
507
511
508 def CanCreateGroup(can_create_in_root=False):
512 def CanCreateGroup(can_create_in_root=False):
509 class _validator(formencode.validators.FancyValidator):
513 class _validator(formencode.validators.FancyValidator):
510 messages = {
514 messages = {
511 'permission_denied': _(u"You don't have permissions "
515 'permission_denied': _(u"You don't have permissions "
512 "to create a group in this location")
516 "to create a group in this location")
513 }
517 }
514
518
515 def to_python(self, value, state):
519 def to_python(self, value, state):
516 #root location
520 #root location
517 if value in [-1, "-1"]:
521 if value in [-1, "-1"]:
518 return None
522 return None
519 return value
523 return value
520
524
521 def validate_python(self, value, state):
525 def validate_python(self, value, state):
522 gr = RepoGroup.get(value)
526 gr = RepoGroup.get(value)
523 gr_name = gr.group_name if gr else None # None means ROOT location
527 gr_name = gr.group_name if gr else None # None means ROOT location
524
528
525 if can_create_in_root and gr is None:
529 if can_create_in_root and gr is None:
526 #we can create in root, we're fine no validations required
530 #we can create in root, we're fine no validations required
527 return
531 return
528
532
529 forbidden_in_root = gr is None and can_create_in_root is False
533 forbidden_in_root = gr is None and can_create_in_root is False
530 val = HasReposGroupPermissionAny('group.admin')
534 val = HasReposGroupPermissionAny('group.admin')
531 forbidden = not val(gr_name, 'can create group validator')
535 forbidden = not val(gr_name, 'can create group validator')
532 if forbidden_in_root or forbidden:
536 if forbidden_in_root or forbidden:
533 msg = M(self, 'permission_denied', state)
537 msg = M(self, 'permission_denied', state)
534 raise formencode.Invalid(msg, value, state,
538 raise formencode.Invalid(msg, value, state,
535 error_dict=dict(group_parent_id=msg)
539 error_dict=dict(group_parent_id=msg)
536 )
540 )
537
541
538 return _validator
542 return _validator
539
543
540
544
541 def ValidPerms(type_='repo'):
545 def ValidPerms(type_='repo'):
542 if type_ == 'group':
546 if type_ == 'group':
543 EMPTY_PERM = 'group.none'
547 EMPTY_PERM = 'group.none'
544 elif type_ == 'repo':
548 elif type_ == 'repo':
545 EMPTY_PERM = 'repository.none'
549 EMPTY_PERM = 'repository.none'
546
550
547 class _validator(formencode.validators.FancyValidator):
551 class _validator(formencode.validators.FancyValidator):
548 messages = {
552 messages = {
549 'perm_new_member_name':
553 'perm_new_member_name':
550 _(u'This username or user group name is not valid')
554 _(u'This username or user group name is not valid')
551 }
555 }
552
556
553 def to_python(self, value, state):
557 def to_python(self, value, state):
554 perms_update = OrderedSet()
558 perms_update = OrderedSet()
555 perms_new = OrderedSet()
559 perms_new = OrderedSet()
556 # build a list of permission to update and new permission to create
560 # build a list of permission to update and new permission to create
557
561
558 #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using
562 #CLEAN OUT ORG VALUE FROM NEW MEMBERS, and group them using
559 new_perms_group = defaultdict(dict)
563 new_perms_group = defaultdict(dict)
560 for k, v in value.copy().iteritems():
564 for k, v in value.copy().iteritems():
561 if k.startswith('perm_new_member'):
565 if k.startswith('perm_new_member'):
562 del value[k]
566 del value[k]
563 _type, part = k.split('perm_new_member_')
567 _type, part = k.split('perm_new_member_')
564 args = part.split('_')
568 args = part.split('_')
565 if len(args) == 1:
569 if len(args) == 1:
566 new_perms_group[args[0]]['perm'] = v
570 new_perms_group[args[0]]['perm'] = v
567 elif len(args) == 2:
571 elif len(args) == 2:
568 _key, pos = args
572 _key, pos = args
569 new_perms_group[pos][_key] = v
573 new_perms_group[pos][_key] = v
570
574
571 # fill new permissions in order of how they were added
575 # fill new permissions in order of how they were added
572 for k in sorted(map(int, new_perms_group.keys())):
576 for k in sorted(map(int, new_perms_group.keys())):
573 perm_dict = new_perms_group[str(k)]
577 perm_dict = new_perms_group[str(k)]
574 new_member = perm_dict.get('name')
578 new_member = perm_dict.get('name')
575 new_perm = perm_dict.get('perm')
579 new_perm = perm_dict.get('perm')
576 new_type = perm_dict.get('type')
580 new_type = perm_dict.get('type')
577 if new_member and new_perm and new_type:
581 if new_member and new_perm and new_type:
578 perms_new.add((new_member, new_perm, new_type))
582 perms_new.add((new_member, new_perm, new_type))
579
583
580 for k, v in value.iteritems():
584 for k, v in value.iteritems():
581 if k.startswith('u_perm_') or k.startswith('g_perm_'):
585 if k.startswith('u_perm_') or k.startswith('g_perm_'):
582 member = k[7:]
586 member = k[7:]
583 t = {'u': 'user',
587 t = {'u': 'user',
584 'g': 'users_group'
588 'g': 'users_group'
585 }[k[0]]
589 }[k[0]]
586 if member == 'default':
590 if member == 'default':
587 if value.get('repo_private'):
591 if value.get('repo_private'):
588 # set none for default when updating to
592 # set none for default when updating to
589 # private repo
593 # private repo
590 v = EMPTY_PERM
594 v = EMPTY_PERM
591 perms_update.add((member, v, t))
595 perms_update.add((member, v, t))
592 #always set NONE when private flag is set
596 #always set NONE when private flag is set
593 if value.get('repo_private'):
597 if value.get('repo_private'):
594 perms_update.add(('default', EMPTY_PERM, 'user'))
598 perms_update.add(('default', EMPTY_PERM, 'user'))
595
599
596 value['perms_updates'] = list(perms_update)
600 value['perms_updates'] = list(perms_update)
597 value['perms_new'] = list(perms_new)
601 value['perms_new'] = list(perms_new)
598
602
599 # update permissions
603 # update permissions
600 for k, v, t in perms_new:
604 for k, v, t in perms_new:
601 try:
605 try:
602 if t is 'user':
606 if t is 'user':
603 self.user_db = User.query()\
607 self.user_db = User.query()\
604 .filter(User.active == True)\
608 .filter(User.active == True)\
605 .filter(User.username == k).one()
609 .filter(User.username == k).one()
606 if t is 'users_group':
610 if t is 'users_group':
607 self.user_db = UserGroup.query()\
611 self.user_db = UserGroup.query()\
608 .filter(UserGroup.users_group_active == True)\
612 .filter(UserGroup.users_group_active == True)\
609 .filter(UserGroup.users_group_name == k).one()
613 .filter(UserGroup.users_group_name == k).one()
610
614
611 except Exception:
615 except Exception:
612 log.exception('Updated permission failed')
616 log.exception('Updated permission failed')
613 msg = M(self, 'perm_new_member_type', state)
617 msg = M(self, 'perm_new_member_type', state)
614 raise formencode.Invalid(msg, value, state,
618 raise formencode.Invalid(msg, value, state,
615 error_dict=dict(perm_new_member_name=msg)
619 error_dict=dict(perm_new_member_name=msg)
616 )
620 )
617 return value
621 return value
618 return _validator
622 return _validator
619
623
620
624
621 def ValidSettings():
625 def ValidSettings():
622 class _validator(formencode.validators.FancyValidator):
626 class _validator(formencode.validators.FancyValidator):
623 def _to_python(self, value, state):
627 def _to_python(self, value, state):
624 # settings form for users that are not admin
628 # settings form for users that are not admin
625 # can't edit certain parameters, it's extra backup if they mangle
629 # can't edit certain parameters, it's extra backup if they mangle
626 # with forms
630 # with forms
627
631
628 forbidden_params = [
632 forbidden_params = [
629 'user', 'repo_type', 'repo_enable_locking',
633 'user', 'repo_type', 'repo_enable_locking',
630 'repo_enable_downloads', 'repo_enable_statistics'
634 'repo_enable_downloads', 'repo_enable_statistics'
631 ]
635 ]
632
636
633 for param in forbidden_params:
637 for param in forbidden_params:
634 if param in value:
638 if param in value:
635 del value[param]
639 del value[param]
636 return value
640 return value
637
641
638 def validate_python(self, value, state):
642 def validate_python(self, value, state):
639 pass
643 pass
640 return _validator
644 return _validator
641
645
642
646
643 def ValidPath():
647 def ValidPath():
644 class _validator(formencode.validators.FancyValidator):
648 class _validator(formencode.validators.FancyValidator):
645 messages = {
649 messages = {
646 'invalid_path': _(u'This is not a valid path')
650 'invalid_path': _(u'This is not a valid path')
647 }
651 }
648
652
649 def validate_python(self, value, state):
653 def validate_python(self, value, state):
650 if not os.path.isdir(value):
654 if not os.path.isdir(value):
651 msg = M(self, 'invalid_path', state)
655 msg = M(self, 'invalid_path', state)
652 raise formencode.Invalid(msg, value, state,
656 raise formencode.Invalid(msg, value, state,
653 error_dict=dict(paths_root_path=msg)
657 error_dict=dict(paths_root_path=msg)
654 )
658 )
655 return _validator
659 return _validator
656
660
657
661
658 def UniqSystemEmail(old_data={}):
662 def UniqSystemEmail(old_data={}):
659 class _validator(formencode.validators.FancyValidator):
663 class _validator(formencode.validators.FancyValidator):
660 messages = {
664 messages = {
661 'email_taken': _(u'This e-mail address is already taken')
665 'email_taken': _(u'This e-mail address is already taken')
662 }
666 }
663
667
664 def _to_python(self, value, state):
668 def _to_python(self, value, state):
665 return value.lower()
669 return value.lower()
666
670
667 def validate_python(self, value, state):
671 def validate_python(self, value, state):
668 if (old_data.get('email') or '').lower() != value:
672 if (old_data.get('email') or '').lower() != value:
669 user = User.get_by_email(value, case_insensitive=True)
673 user = User.get_by_email(value, case_insensitive=True)
670 if user:
674 if user:
671 msg = M(self, 'email_taken', state)
675 msg = M(self, 'email_taken', state)
672 raise formencode.Invalid(msg, value, state,
676 raise formencode.Invalid(msg, value, state,
673 error_dict=dict(email=msg)
677 error_dict=dict(email=msg)
674 )
678 )
675 return _validator
679 return _validator
676
680
677
681
678 def ValidSystemEmail():
682 def ValidSystemEmail():
679 class _validator(formencode.validators.FancyValidator):
683 class _validator(formencode.validators.FancyValidator):
680 messages = {
684 messages = {
681 'non_existing_email': _(u'e-mail "%(email)s" does not exist.')
685 'non_existing_email': _(u'e-mail "%(email)s" does not exist.')
682 }
686 }
683
687
684 def _to_python(self, value, state):
688 def _to_python(self, value, state):
685 return value.lower()
689 return value.lower()
686
690
687 def validate_python(self, value, state):
691 def validate_python(self, value, state):
688 user = User.get_by_email(value, case_insensitive=True)
692 user = User.get_by_email(value, case_insensitive=True)
689 if user is None:
693 if user is None:
690 msg = M(self, 'non_existing_email', state, email=value)
694 msg = M(self, 'non_existing_email', state, email=value)
691 raise formencode.Invalid(msg, value, state,
695 raise formencode.Invalid(msg, value, state,
692 error_dict=dict(email=msg)
696 error_dict=dict(email=msg)
693 )
697 )
694
698
695 return _validator
699 return _validator
696
700
697
701
698 def LdapLibValidator():
702 def LdapLibValidator():
699 class _validator(formencode.validators.FancyValidator):
703 class _validator(formencode.validators.FancyValidator):
700 messages = {
704 messages = {
701
705
702 }
706 }
703
707
704 def validate_python(self, value, state):
708 def validate_python(self, value, state):
705 try:
709 try:
706 import ldap
710 import ldap
707 ldap # pyflakes silence !
711 ldap # pyflakes silence !
708 except ImportError:
712 except ImportError:
709 raise LdapImportError()
713 raise LdapImportError()
710
714
711 return _validator
715 return _validator
712
716
713
717
714 def AttrLoginValidator():
718 def AttrLoginValidator():
715 class _validator(formencode.validators.FancyValidator):
719 class _validator(formencode.validators.FancyValidator):
716 messages = {
720 messages = {
717 'invalid_cn':
721 'invalid_cn':
718 _(u'The LDAP Login attribute of the CN must be specified - '
722 _(u'The LDAP Login attribute of the CN must be specified - '
719 'this is the name of the attribute that is equivalent '
723 'this is the name of the attribute that is equivalent '
720 'to "username"')
724 'to "username"')
721 }
725 }
722
726
723 def validate_python(self, value, state):
727 def validate_python(self, value, state):
724 if not value or not isinstance(value, (str, unicode)):
728 if not value or not isinstance(value, (str, unicode)):
725 msg = M(self, 'invalid_cn', state)
729 msg = M(self, 'invalid_cn', state)
726 raise formencode.Invalid(msg, value, state,
730 raise formencode.Invalid(msg, value, state,
727 error_dict=dict(ldap_attr_login=msg)
731 error_dict=dict(ldap_attr_login=msg)
728 )
732 )
729
733
730 return _validator
734 return _validator
731
735
732
736
733 def NotReviewedRevisions(repo_id):
737 def NotReviewedRevisions(repo_id):
734 class _validator(formencode.validators.FancyValidator):
738 class _validator(formencode.validators.FancyValidator):
735 messages = {
739 messages = {
736 'rev_already_reviewed':
740 'rev_already_reviewed':
737 _(u'Revisions %(revs)s are already part of pull request '
741 _(u'Revisions %(revs)s are already part of pull request '
738 'or have set status')
742 'or have set status')
739 }
743 }
740
744
741 def validate_python(self, value, state):
745 def validate_python(self, value, state):
742 # check revisions if they are not reviewed, or a part of another
746 # check revisions if they are not reviewed, or a part of another
743 # pull request
747 # pull request
744 statuses = ChangesetStatus.query()\
748 statuses = ChangesetStatus.query()\
745 .filter(ChangesetStatus.revision.in_(value))\
749 .filter(ChangesetStatus.revision.in_(value))\
746 .filter(ChangesetStatus.repo_id == repo_id)\
750 .filter(ChangesetStatus.repo_id == repo_id)\
747 .all()
751 .all()
748
752
749 errors = []
753 errors = []
750 for cs in statuses:
754 for cs in statuses:
751 if cs.pull_request_id:
755 if cs.pull_request_id:
752 errors.append(['pull_req', cs.revision[:12]])
756 errors.append(['pull_req', cs.revision[:12]])
753 elif cs.status:
757 elif cs.status:
754 errors.append(['status', cs.revision[:12]])
758 errors.append(['status', cs.revision[:12]])
755
759
756 if errors:
760 if errors:
757 revs = ','.join([x[1] for x in errors])
761 revs = ','.join([x[1] for x in errors])
758 msg = M(self, 'rev_already_reviewed', state, revs=revs)
762 msg = M(self, 'rev_already_reviewed', state, revs=revs)
759 raise formencode.Invalid(msg, value, state,
763 raise formencode.Invalid(msg, value, state,
760 error_dict=dict(revisions=revs)
764 error_dict=dict(revisions=revs)
761 )
765 )
762
766
763 return _validator
767 return _validator
764
768
765
769
766 def ValidIp():
770 def ValidIp():
767 class _validator(CIDR):
771 class _validator(CIDR):
768 messages = dict(
772 messages = dict(
769 badFormat=_('Please enter a valid IPv4 or IpV6 address'),
773 badFormat=_('Please enter a valid IPv4 or IpV6 address'),
770 illegalBits=_('The network size (bits) must be within the range'
774 illegalBits=_('The network size (bits) must be within the range'
771 ' of 0-32 (not %(bits)r)'))
775 ' of 0-32 (not %(bits)r)'))
772
776
773 def to_python(self, value, state):
777 def to_python(self, value, state):
774 v = super(_validator, self).to_python(value, state)
778 v = super(_validator, self).to_python(value, state)
775 v = v.strip()
779 v = v.strip()
776 net = ipaddr.IPNetwork(address=v)
780 net = ipaddr.IPNetwork(address=v)
777 if isinstance(net, ipaddr.IPv4Network):
781 if isinstance(net, ipaddr.IPv4Network):
778 #if IPv4 doesn't end with a mask, add /32
782 #if IPv4 doesn't end with a mask, add /32
779 if '/' not in value:
783 if '/' not in value:
780 v += '/32'
784 v += '/32'
781 if isinstance(net, ipaddr.IPv6Network):
785 if isinstance(net, ipaddr.IPv6Network):
782 #if IPv6 doesn't end with a mask, add /128
786 #if IPv6 doesn't end with a mask, add /128
783 if '/' not in value:
787 if '/' not in value:
784 v += '/128'
788 v += '/128'
785 return v
789 return v
786
790
787 def validate_python(self, value, state):
791 def validate_python(self, value, state):
788 try:
792 try:
789 addr = value.strip()
793 addr = value.strip()
790 #this raises an ValueError if address is not IpV4 or IpV6
794 #this raises an ValueError if address is not IpV4 or IpV6
791 ipaddr.IPNetwork(address=addr)
795 ipaddr.IPNetwork(address=addr)
792 except ValueError:
796 except ValueError:
793 raise formencode.Invalid(self.message('badFormat', state),
797 raise formencode.Invalid(self.message('badFormat', state),
794 value, state)
798 value, state)
795
799
796 return _validator
800 return _validator
797
801
798
802
799 def FieldKey():
803 def FieldKey():
800 class _validator(formencode.validators.FancyValidator):
804 class _validator(formencode.validators.FancyValidator):
801 messages = dict(
805 messages = dict(
802 badFormat=_('Key name can only consist of letters, '
806 badFormat=_('Key name can only consist of letters, '
803 'underscore, dash or numbers'),)
807 'underscore, dash or numbers'),)
804
808
805 def validate_python(self, value, state):
809 def validate_python(self, value, state):
806 if not re.match('[a-zA-Z0-9_-]+$', value):
810 if not re.match('[a-zA-Z0-9_-]+$', value):
807 raise formencode.Invalid(self.message('badFormat', state),
811 raise formencode.Invalid(self.message('badFormat', state),
808 value, state)
812 value, state)
809 return _validator
813 return _validator
General Comments 0
You need to be logged in to leave comments. Login now