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