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