##// END OF EJS Templates
Switched forms to new validators
marcink -
r2467:4419551b codereview
parent child Browse files
Show More
@@ -220,7 +220,7 b' class UsersController(BaseController):'
220 return redirect(url('edit_user', id=id))
220 return redirect(url('edit_user', id=id))
221
221
222 def add_email(self, id):
222 def add_email(self, id):
223 """PUT /user_emails/id: Update an existing item"""
223 """POST /user_emails:Add an existing item"""
224 # url('user_emails', id=ID, method='put')
224 # url('user_emails', id=ID, method='put')
225
225
226 #TODO: validation and form !!!
226 #TODO: validation and form !!!
This diff has been collapsed as it changes many lines, (753 lines changed) Show them Hide them
@@ -19,573 +19,76 b' list=[1,2,3,4,5]'
19 for SELECT use formencode.All(OneOf(list), Int())
19 for SELECT use formencode.All(OneOf(list), Int())
20
20
21 """
21 """
22 import os
23 import re
24 import logging
22 import logging
25 import traceback
26
23
27 import formencode
24 import formencode
28 from formencode import All
25 from formencode import All
29 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
30 Email, Bool, StringBoolean, Set
31
26
32 from pylons.i18n.translation import _
27 from pylons.i18n.translation import _
33 from webhelpers.pylonslib.secure_form import authentication_token
34
28
35 from rhodecode.config.routing import ADMIN_PREFIX
29 from rhodecode.model import validators as v
36 from rhodecode.lib.utils import repo_name_slug
37 from rhodecode.lib.auth import authenticate, get_crypt_password
38 from rhodecode.lib.exceptions import LdapImportError
39 from rhodecode.model.db import User, UsersGroup, RepoGroup, Repository
40 from rhodecode import BACKENDS
30 from rhodecode import BACKENDS
41
31
42 log = logging.getLogger(__name__)
32 log = logging.getLogger(__name__)
43
33
44
34
45 #this is needed to translate the messages using _() in validators
46 class State_obj(object):
47 _ = staticmethod(_)
48
49
50 #==============================================================================
51 # VALIDATORS
52 #==============================================================================
53 class ValidAuthToken(formencode.validators.FancyValidator):
54 messages = {'invalid_token': _('Token mismatch')}
55
56 def validate_python(self, value, state):
57
58 if value != authentication_token():
59 raise formencode.Invalid(
60 self.message('invalid_token',
61 state, search_number=value),
62 value,
63 state
64 )
65
66
67 def ValidUsername(edit, old_data):
68 class _ValidUsername(formencode.validators.FancyValidator):
69
70 def validate_python(self, value, state):
71 if value in ['default', 'new_user']:
72 raise formencode.Invalid(_('Invalid username'), value, state)
73 #check if user is unique
74 old_un = None
75 if edit:
76 old_un = User.get(old_data.get('user_id')).username
77
78 if old_un != value or not edit:
79 if User.get_by_username(value, case_insensitive=True):
80 raise formencode.Invalid(_('This username already '
81 'exists') , value, state)
82
83 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
84 raise formencode.Invalid(
85 _('Username may only contain alphanumeric characters '
86 'underscores, periods or dashes and must begin with '
87 'alphanumeric character'),
88 value,
89 state
90 )
91
92 return _ValidUsername
93
94
95 def ValidUsersGroup(edit, old_data):
96
97 class _ValidUsersGroup(formencode.validators.FancyValidator):
98
99 def validate_python(self, value, state):
100 if value in ['default']:
101 raise formencode.Invalid(_('Invalid group name'), value, state)
102 #check if group is unique
103 old_ugname = None
104 if edit:
105 old_ugname = UsersGroup.get(
106 old_data.get('users_group_id')).users_group_name
107
108 if old_ugname != value or not edit:
109 if UsersGroup.get_by_group_name(value, cache=False,
110 case_insensitive=True):
111 raise formencode.Invalid(_('This users group '
112 'already exists'), value,
113 state)
114
115 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
116 raise formencode.Invalid(
117 _('RepoGroup name may only contain alphanumeric characters '
118 'underscores, periods or dashes and must begin with '
119 'alphanumeric character'),
120 value,
121 state
122 )
123
124 return _ValidUsersGroup
125
126
127 def ValidReposGroup(edit, old_data):
128 class _ValidReposGroup(formencode.validators.FancyValidator):
129
130 def validate_python(self, value, state):
131 # TODO WRITE VALIDATIONS
132 group_name = value.get('group_name')
133 group_parent_id = value.get('group_parent_id')
134
135 # slugify repo group just in case :)
136 slug = repo_name_slug(group_name)
137
138 # check for parent of self
139 parent_of_self = lambda: (
140 old_data['group_id'] == int(group_parent_id)
141 if group_parent_id else False
142 )
143 if edit and parent_of_self():
144 e_dict = {
145 'group_parent_id': _('Cannot assign this group as parent')
146 }
147 raise formencode.Invalid('', value, state,
148 error_dict=e_dict)
149
150 old_gname = None
151 if edit:
152 old_gname = RepoGroup.get(old_data.get('group_id')).group_name
153
154 if old_gname != group_name or not edit:
155
156 # check group
157 gr = RepoGroup.query()\
158 .filter(RepoGroup.group_name == slug)\
159 .filter(RepoGroup.group_parent_id == group_parent_id)\
160 .scalar()
161
162 if gr:
163 e_dict = {
164 'group_name': _('This group already exists')
165 }
166 raise formencode.Invalid('', value, state,
167 error_dict=e_dict)
168
169 # check for same repo
170 repo = Repository.query()\
171 .filter(Repository.repo_name == slug)\
172 .scalar()
173
174 if repo:
175 e_dict = {
176 'group_name': _('Repository with this name already exists')
177 }
178 raise formencode.Invalid('', value, state,
179 error_dict=e_dict)
180
181 return _ValidReposGroup
182
183
184 class ValidPassword(formencode.validators.FancyValidator):
185
186 def to_python(self, value, state):
187
188 if not value:
189 return
190
191 if value.get('password'):
192 try:
193 value['password'] = get_crypt_password(value['password'])
194 except UnicodeEncodeError:
195 e_dict = {'password': _('Invalid characters in password')}
196 raise formencode.Invalid('', value, state, error_dict=e_dict)
197
198 if value.get('password_confirmation'):
199 try:
200 value['password_confirmation'] = \
201 get_crypt_password(value['password_confirmation'])
202 except UnicodeEncodeError:
203 e_dict = {
204 'password_confirmation': _('Invalid characters in password')
205 }
206 raise formencode.Invalid('', value, state, error_dict=e_dict)
207
208 if value.get('new_password'):
209 try:
210 value['new_password'] = \
211 get_crypt_password(value['new_password'])
212 except UnicodeEncodeError:
213 e_dict = {'new_password': _('Invalid characters in password')}
214 raise formencode.Invalid('', value, state, error_dict=e_dict)
215
216 return value
217
218
219 class ValidPasswordsMatch(formencode.validators.FancyValidator):
220
221 def validate_python(self, value, state):
222
223 pass_val = value.get('password') or value.get('new_password')
224 if pass_val != value['password_confirmation']:
225 e_dict = {'password_confirmation':
226 _('Passwords do not match')}
227 raise formencode.Invalid('', value, state, error_dict=e_dict)
228
229
230 class ValidAuth(formencode.validators.FancyValidator):
231 messages = {
232 'invalid_password':_('invalid password'),
233 'invalid_login':_('invalid user name'),
234 'disabled_account':_('Your account is disabled')
235 }
236
237 # error mapping
238 e_dict = {'username': messages['invalid_login'],
239 'password': messages['invalid_password']}
240 e_dict_disable = {'username': messages['disabled_account']}
241
242 def validate_python(self, value, state):
243 password = value['password']
244 username = value['username']
245 user = User.get_by_username(username)
246
247 if authenticate(username, password):
248 return value
249 else:
250 if user and user.active is False:
251 log.warning('user %s is disabled' % username)
252 raise formencode.Invalid(
253 self.message('disabled_account',
254 state=State_obj),
255 value, state,
256 error_dict=self.e_dict_disable
257 )
258 else:
259 log.warning('user %s failed to authenticate' % username)
260 raise formencode.Invalid(
261 self.message('invalid_password',
262 state=State_obj), value, state,
263 error_dict=self.e_dict
264 )
265
266
267 class ValidRepoUser(formencode.validators.FancyValidator):
268
269 def to_python(self, value, state):
270 try:
271 User.query().filter(User.active == True)\
272 .filter(User.username == value).one()
273 except Exception:
274 raise formencode.Invalid(_('This username is not valid'),
275 value, state)
276 return value
277
278
279 def ValidRepoName(edit, old_data):
280 class _ValidRepoName(formencode.validators.FancyValidator):
281 def to_python(self, value, state):
282
283 repo_name = value.get('repo_name')
284
285 slug = repo_name_slug(repo_name)
286 if slug in [ADMIN_PREFIX, '']:
287 e_dict = {'repo_name': _('This repository name is disallowed')}
288 raise formencode.Invalid('', value, state, error_dict=e_dict)
289
290 if value.get('repo_group'):
291 gr = RepoGroup.get(value.get('repo_group'))
292 group_path = gr.full_path
293 # value needs to be aware of group name in order to check
294 # db key This is an actual just the name to store in the
295 # database
296 repo_name_full = group_path + RepoGroup.url_sep() + repo_name
297
298 else:
299 group_path = ''
300 repo_name_full = repo_name
301
302 value['repo_name_full'] = repo_name_full
303 rename = old_data.get('repo_name') != repo_name_full
304 create = not edit
305 if rename or create:
306
307 if group_path != '':
308 if Repository.get_by_repo_name(repo_name_full):
309 e_dict = {
310 'repo_name': _('This repository already exists in '
311 'a group "%s"') % gr.group_name
312 }
313 raise formencode.Invalid('', value, state,
314 error_dict=e_dict)
315 elif RepoGroup.get_by_group_name(repo_name_full):
316 e_dict = {
317 'repo_name': _('There is a group with this name '
318 'already "%s"') % repo_name_full
319 }
320 raise formencode.Invalid('', value, state,
321 error_dict=e_dict)
322
323 elif Repository.get_by_repo_name(repo_name_full):
324 e_dict = {'repo_name': _('This repository '
325 'already exists')}
326 raise formencode.Invalid('', value, state,
327 error_dict=e_dict)
328
329 return value
330
331 return _ValidRepoName
332
333
334 def ValidForkName(*args, **kwargs):
335 return ValidRepoName(*args, **kwargs)
336
337
338 def SlugifyName():
339 class _SlugifyName(formencode.validators.FancyValidator):
340
341 def to_python(self, value, state):
342 return repo_name_slug(value)
343
344 return _SlugifyName
345
346
347 def ValidCloneUri():
348 from rhodecode.lib.utils import make_ui
349
350 def url_handler(repo_type, url, proto, ui=None):
351 if repo_type == 'hg':
352 from mercurial.httprepo import httprepository, httpsrepository
353 if proto == 'https':
354 httpsrepository(make_ui('db'), url).capabilities
355 elif proto == 'http':
356 httprepository(make_ui('db'), url).capabilities
357 elif repo_type == 'git':
358 #TODO: write a git url validator
359 pass
360
361 class _ValidCloneUri(formencode.validators.FancyValidator):
362
363 def to_python(self, value, state):
364
365 repo_type = value.get('repo_type')
366 url = value.get('clone_uri')
367 e_dict = {'clone_uri': _('invalid clone url')}
368
369 if not url:
370 pass
371 elif url.startswith('https'):
372 try:
373 url_handler(repo_type, url, 'https', make_ui('db'))
374 except Exception:
375 log.error(traceback.format_exc())
376 raise formencode.Invalid('', value, state, error_dict=e_dict)
377 elif url.startswith('http'):
378 try:
379 url_handler(repo_type, url, 'http', make_ui('db'))
380 except Exception:
381 log.error(traceback.format_exc())
382 raise formencode.Invalid('', value, state, error_dict=e_dict)
383 else:
384 e_dict = {'clone_uri': _('Invalid clone url, provide a '
385 'valid clone http\s url')}
386 raise formencode.Invalid('', value, state, error_dict=e_dict)
387
388 return value
389
390 return _ValidCloneUri
391
392
393 def ValidForkType(old_data):
394 class _ValidForkType(formencode.validators.FancyValidator):
395
396 def to_python(self, value, state):
397 if old_data['repo_type'] != value:
398 raise formencode.Invalid(_('Fork have to be the same '
399 'type as original'), value, state)
400
401 return value
402 return _ValidForkType
403
404
405 def ValidPerms(type_='repo'):
406 if type_ == 'group':
407 EMPTY_PERM = 'group.none'
408 elif type_ == 'repo':
409 EMPTY_PERM = 'repository.none'
410
411 class _ValidPerms(formencode.validators.FancyValidator):
412 messages = {
413 'perm_new_member_name':
414 _('This username or users group name is not valid')
415 }
416
417 def to_python(self, value, state):
418 perms_update = []
419 perms_new = []
420 # build a list of permission to update and new permission to create
421 for k, v in value.items():
422 # means new added member to permissions
423 if k.startswith('perm_new_member'):
424 new_perm = value.get('perm_new_member', False)
425 new_member = value.get('perm_new_member_name', False)
426 new_type = value.get('perm_new_member_type')
427
428 if new_member and new_perm:
429 if (new_member, new_perm, new_type) not in perms_new:
430 perms_new.append((new_member, new_perm, new_type))
431 elif k.startswith('u_perm_') or k.startswith('g_perm_'):
432 member = k[7:]
433 t = {'u': 'user',
434 'g': 'users_group'
435 }[k[0]]
436 if member == 'default':
437 if value.get('private'):
438 # set none for default when updating to private repo
439 v = EMPTY_PERM
440 perms_update.append((member, v, t))
441
442 value['perms_updates'] = perms_update
443 value['perms_new'] = perms_new
444
445 # update permissions
446 for k, v, t in perms_new:
447 try:
448 if t is 'user':
449 self.user_db = User.query()\
450 .filter(User.active == True)\
451 .filter(User.username == k).one()
452 if t is 'users_group':
453 self.user_db = UsersGroup.query()\
454 .filter(UsersGroup.users_group_active == True)\
455 .filter(UsersGroup.users_group_name == k).one()
456
457 except Exception:
458 msg = self.message('perm_new_member_name',
459 state=State_obj)
460 raise formencode.Invalid(
461 msg, value, state, error_dict={'perm_new_member_name': msg}
462 )
463 return value
464 return _ValidPerms
465
466
467 class ValidSettings(formencode.validators.FancyValidator):
468
469 def to_python(self, value, state):
470 # settings form can't edit user
471 if 'user' in value:
472 del['value']['user']
473 return value
474
475
476 class ValidPath(formencode.validators.FancyValidator):
477 def to_python(self, value, state):
478
479 if not os.path.isdir(value):
480 msg = _('This is not a valid path')
481 raise formencode.Invalid(msg, value, state,
482 error_dict={'paths_root_path': msg})
483 return value
484
485
486 def UniqSystemEmail(old_data):
487 class _UniqSystemEmail(formencode.validators.FancyValidator):
488 def to_python(self, value, state):
489 value = value.lower()
490 if (old_data.get('email') or '').lower() != value:
491 user = User.get_by_email(value, case_insensitive=True)
492 if user:
493 raise formencode.Invalid(
494 _("This e-mail address is already taken"), value, state
495 )
496 return value
497
498 return _UniqSystemEmail
499
500
501 class ValidSystemEmail(formencode.validators.FancyValidator):
502 def to_python(self, value, state):
503 value = value.lower()
504 user = User.get_by_email(value, case_insensitive=True)
505 if user is None:
506 raise formencode.Invalid(
507 _("This e-mail address doesn't exist."), value, state
508 )
509
510 return value
511
512
513 class LdapLibValidator(formencode.validators.FancyValidator):
514
515 def to_python(self, value, state):
516
517 try:
518 import ldap
519 except ImportError:
520 raise LdapImportError
521 return value
522
523
524 class AttrLoginValidator(formencode.validators.FancyValidator):
525
526 def to_python(self, value, state):
527
528 if not value or not isinstance(value, (str, unicode)):
529 raise formencode.Invalid(
530 _("The LDAP Login attribute of the CN must be specified - "
531 "this is the name of the attribute that is equivalent "
532 "to 'username'"), value, state
533 )
534
535 return value
536
537
538 #==============================================================================
539 # FORMS
540 #==============================================================================
541 class LoginForm(formencode.Schema):
35 class LoginForm(formencode.Schema):
542 allow_extra_fields = True
36 allow_extra_fields = True
543 filter_extra_fields = True
37 filter_extra_fields = True
544 username = UnicodeString(
38 username = v.UnicodeString(
545 strip=True,
39 strip=True,
546 min=1,
40 min=1,
547 not_empty=True,
41 not_empty=True,
548 messages={
42 messages={
549 'empty': _('Please enter a login'),
43 'empty': _(u'Please enter a login'),
550 'tooShort': _('Enter a value %(min)i characters long or more')}
44 'tooShort': _(u'Enter a value %(min)i characters long or more')}
551 )
45 )
552
46
553 password = UnicodeString(
47 password = v.UnicodeString(
554 strip=False,
48 strip=False,
555 min=3,
49 min=3,
556 not_empty=True,
50 not_empty=True,
557 messages={
51 messages={
558 'empty': _('Please enter a password'),
52 'empty': _(u'Please enter a password'),
559 'tooShort': _('Enter %(min)i characters or more')}
53 'tooShort': _(u'Enter %(min)i characters or more')}
560 )
54 )
561
55
562 remember = StringBoolean(if_missing=False)
56 remember = v.StringBoolean(if_missing=False)
563
57
564 chained_validators = [ValidAuth]
58 chained_validators = [v.ValidAuth()]
565
59
566
60
567 def UserForm(edit=False, old_data={}):
61 def UserForm(edit=False, old_data={}):
568 class _UserForm(formencode.Schema):
62 class _UserForm(formencode.Schema):
569 allow_extra_fields = True
63 allow_extra_fields = True
570 filter_extra_fields = True
64 filter_extra_fields = True
571 username = All(UnicodeString(strip=True, min=1, not_empty=True),
65 username = All(v.UnicodeString(strip=True, min=1, not_empty=True),
572 ValidUsername(edit, old_data))
66 v.ValidUsername(edit, old_data))
573 if edit:
67 if edit:
574 new_password = All(UnicodeString(strip=False, min=6, not_empty=False))
68 new_password = All(
575 password_confirmation = All(UnicodeString(strip=False, min=6,
69 v.UnicodeString(strip=False, min=6, not_empty=False)
576 not_empty=False))
70 )
577 admin = StringBoolean(if_missing=False)
71 password_confirmation = All(
72 v.ValidPassword(),
73 v.UnicodeString(strip=False, min=6, not_empty=False),
74 )
75 admin = v.StringBoolean(if_missing=False)
578 else:
76 else:
579 password = All(UnicodeString(strip=False, min=6, not_empty=True))
77 password = All(
580 password_confirmation = All(UnicodeString(strip=False, min=6,
78 v.ValidPassword(),
581 not_empty=False))
79 v.UnicodeString(strip=False, min=6, not_empty=True)
80 )
81 password_confirmation = All(
82 v.ValidPassword(),
83 v.UnicodeString(strip=False, min=6, not_empty=False)
84 )
582
85
583 active = StringBoolean(if_missing=False)
86 active = v.StringBoolean(if_missing=False)
584 name = UnicodeString(strip=True, min=1, not_empty=False)
87 name = v.UnicodeString(strip=True, min=1, not_empty=False)
585 lastname = UnicodeString(strip=True, min=1, not_empty=False)
88 lastname = v.UnicodeString(strip=True, min=1, not_empty=False)
586 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
89 email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data))
587
90
588 chained_validators = [ValidPasswordsMatch, ValidPassword]
91 chained_validators = [v.ValidPasswordsMatch()]
589
92
590 return _UserForm
93 return _UserForm
591
94
@@ -595,15 +98,18 b' def UsersGroupForm(edit=False, old_data='
595 allow_extra_fields = True
98 allow_extra_fields = True
596 filter_extra_fields = True
99 filter_extra_fields = True
597
100
598 users_group_name = All(UnicodeString(strip=True, min=1, not_empty=True),
101 users_group_name = All(
599 ValidUsersGroup(edit, old_data))
102 v.UnicodeString(strip=True, min=1, not_empty=True),
103 v.ValidUsersGroup(edit, old_data)
104 )
600
105
601 users_group_active = StringBoolean(if_missing=False)
106 users_group_active = v.StringBoolean(if_missing=False)
602
107
603 if edit:
108 if edit:
604 users_group_members = OneOf(available_members, hideList=False,
109 users_group_members = v.OneOf(
605 testValueList=True,
110 available_members, hideList=False, testValueList=True,
606 if_missing=None, not_empty=False)
111 if_missing=None, not_empty=False
112 )
607
113
608 return _UsersGroupForm
114 return _UsersGroupForm
609
115
@@ -613,15 +119,16 b' def ReposGroupForm(edit=False, old_data='
613 allow_extra_fields = True
119 allow_extra_fields = True
614 filter_extra_fields = False
120 filter_extra_fields = False
615
121
616 group_name = All(UnicodeString(strip=True, min=1, not_empty=True),
122 group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
617 SlugifyName())
123 v.SlugifyName())
618 group_description = UnicodeString(strip=True, min=1,
124 group_description = v.UnicodeString(strip=True, min=1,
619 not_empty=True)
125 not_empty=True)
620 group_parent_id = OneOf(available_groups, hideList=False,
126 group_parent_id = v.OneOf(available_groups, hideList=False,
621 testValueList=True,
127 testValueList=True,
622 if_missing=None, not_empty=False)
128 if_missing=None, not_empty=False)
623
129
624 chained_validators = [ValidReposGroup(edit, old_data), ValidPerms('group')]
130 chained_validators = [v.ValidReposGroup(edit, old_data),
131 v.ValidPerms('group')]
625
132
626 return _ReposGroupForm
133 return _ReposGroupForm
627
134
@@ -630,16 +137,24 b' def RegisterForm(edit=False, old_data={}'
630 class _RegisterForm(formencode.Schema):
137 class _RegisterForm(formencode.Schema):
631 allow_extra_fields = True
138 allow_extra_fields = True
632 filter_extra_fields = True
139 filter_extra_fields = True
633 username = All(ValidUsername(edit, old_data),
140 username = All(
634 UnicodeString(strip=True, min=1, not_empty=True))
141 v.ValidUsername(edit, old_data),
635 password = All(UnicodeString(strip=False, min=6, not_empty=True))
142 v.UnicodeString(strip=True, min=1, not_empty=True)
636 password_confirmation = All(UnicodeString(strip=False, min=6, not_empty=True))
143 )
637 active = StringBoolean(if_missing=False)
144 password = All(
638 name = UnicodeString(strip=True, min=1, not_empty=False)
145 v.ValidPassword(),
639 lastname = UnicodeString(strip=True, min=1, not_empty=False)
146 v.UnicodeString(strip=False, min=6, not_empty=True)
640 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
147 )
148 password_confirmation = All(
149 v.ValidPassword(),
150 v.UnicodeString(strip=False, min=6, not_empty=True)
151 )
152 active = v.StringBoolean(if_missing=False)
153 name = v.UnicodeString(strip=True, min=1, not_empty=False)
154 lastname = v.UnicodeString(strip=True, min=1, not_empty=False)
155 email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data))
641
156
642 chained_validators = [ValidPasswordsMatch, ValidPassword]
157 chained_validators = [v.ValidPasswordsMatch()]
643
158
644 return _RegisterForm
159 return _RegisterForm
645
160
@@ -648,7 +163,7 b' def PasswordResetForm():'
648 class _PasswordResetForm(formencode.Schema):
163 class _PasswordResetForm(formencode.Schema):
649 allow_extra_fields = True
164 allow_extra_fields = True
650 filter_extra_fields = True
165 filter_extra_fields = True
651 email = All(ValidSystemEmail(), Email(not_empty=True))
166 email = All(v.ValidSystemEmail(), v.Email(not_empty=True))
652 return _PasswordResetForm
167 return _PasswordResetForm
653
168
654
169
@@ -657,24 +172,24 b' def RepoForm(edit=False, old_data={}, su'
657 class _RepoForm(formencode.Schema):
172 class _RepoForm(formencode.Schema):
658 allow_extra_fields = True
173 allow_extra_fields = True
659 filter_extra_fields = False
174 filter_extra_fields = False
660 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True),
175 repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
661 SlugifyName())
176 v.SlugifyName())
662 clone_uri = All(UnicodeString(strip=True, min=1, not_empty=False))
177 clone_uri = All(v.UnicodeString(strip=True, min=1, not_empty=False))
663 repo_group = OneOf(repo_groups, hideList=True)
178 repo_group = v.OneOf(repo_groups, hideList=True)
664 repo_type = OneOf(supported_backends)
179 repo_type = v.OneOf(supported_backends)
665 description = UnicodeString(strip=True, min=1, not_empty=False)
180 description = v.UnicodeString(strip=True, min=1, not_empty=False)
666 private = StringBoolean(if_missing=False)
181 private = v.StringBoolean(if_missing=False)
667 enable_statistics = StringBoolean(if_missing=False)
182 enable_statistics = v.StringBoolean(if_missing=False)
668 enable_downloads = StringBoolean(if_missing=False)
183 enable_downloads = v.StringBoolean(if_missing=False)
669 landing_rev = OneOf(landing_revs, hideList=True)
184 landing_rev = v.OneOf(landing_revs, hideList=True)
670
185
671 if edit:
186 if edit:
672 #this is repo owner
187 #this is repo owner
673 user = All(UnicodeString(not_empty=True), ValidRepoUser)
188 user = All(v.UnicodeString(not_empty=True), v.ValidRepoUser())
674
189
675 chained_validators = [ValidCloneUri()(),
190 chained_validators = [v.ValidCloneUri(),
676 ValidRepoName(edit, old_data),
191 v.ValidRepoName(edit, old_data),
677 ValidPerms()]
192 v.ValidPerms()]
678 return _RepoForm
193 return _RepoForm
679
194
680
195
@@ -683,33 +198,34 b' def RepoForkForm(edit=False, old_data={}'
683 class _RepoForkForm(formencode.Schema):
198 class _RepoForkForm(formencode.Schema):
684 allow_extra_fields = True
199 allow_extra_fields = True
685 filter_extra_fields = False
200 filter_extra_fields = False
686 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True),
201 repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
687 SlugifyName())
202 v.SlugifyName())
688 repo_group = OneOf(repo_groups, hideList=True)
203 repo_group = v.OneOf(repo_groups, hideList=True)
689 repo_type = All(ValidForkType(old_data), OneOf(supported_backends))
204 repo_type = All(v.ValidForkType(old_data), v.OneOf(supported_backends))
690 description = UnicodeString(strip=True, min=1, not_empty=True)
205 description = v.UnicodeString(strip=True, min=1, not_empty=True)
691 private = StringBoolean(if_missing=False)
206 private = v.StringBoolean(if_missing=False)
692 copy_permissions = StringBoolean(if_missing=False)
207 copy_permissions = v.StringBoolean(if_missing=False)
693 update_after_clone = StringBoolean(if_missing=False)
208 update_after_clone = v.StringBoolean(if_missing=False)
694 fork_parent_id = UnicodeString()
209 fork_parent_id = v.UnicodeString()
695 chained_validators = [ValidForkName(edit, old_data)]
210 chained_validators = [v.ValidForkName(edit, old_data)]
696
211
697 return _RepoForkForm
212 return _RepoForkForm
698
213
699
214
700 def RepoSettingsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
215 def RepoSettingsForm(edit=False, old_data={},
701 repo_groups=[], landing_revs=[]):
216 supported_backends=BACKENDS.keys(), repo_groups=[],
217 landing_revs=[]):
702 class _RepoForm(formencode.Schema):
218 class _RepoForm(formencode.Schema):
703 allow_extra_fields = True
219 allow_extra_fields = True
704 filter_extra_fields = False
220 filter_extra_fields = False
705 repo_name = All(UnicodeString(strip=True, min=1, not_empty=True),
221 repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
706 SlugifyName())
222 v.SlugifyName())
707 description = UnicodeString(strip=True, min=1, not_empty=True)
223 description = v.UnicodeString(strip=True, min=1, not_empty=True)
708 repo_group = OneOf(repo_groups, hideList=True)
224 repo_group = v.OneOf(repo_groups, hideList=True)
709 private = StringBoolean(if_missing=False)
225 private = v.StringBoolean(if_missing=False)
710 landing_rev = OneOf(landing_revs, hideList=True)
226 landing_rev = v.OneOf(landing_revs, hideList=True)
711 chained_validators = [ValidRepoName(edit, old_data), ValidPerms(),
227 chained_validators = [v.ValidRepoName(edit, old_data), v.ValidPerms(),
712 ValidSettings]
228 v.ValidSettings()]
713 return _RepoForm
229 return _RepoForm
714
230
715
231
@@ -717,9 +233,9 b' def ApplicationSettingsForm():'
717 class _ApplicationSettingsForm(formencode.Schema):
233 class _ApplicationSettingsForm(formencode.Schema):
718 allow_extra_fields = True
234 allow_extra_fields = True
719 filter_extra_fields = False
235 filter_extra_fields = False
720 rhodecode_title = UnicodeString(strip=True, min=1, not_empty=True)
236 rhodecode_title = v.UnicodeString(strip=True, min=1, not_empty=True)
721 rhodecode_realm = UnicodeString(strip=True, min=1, not_empty=True)
237 rhodecode_realm = v.UnicodeString(strip=True, min=1, not_empty=True)
722 rhodecode_ga_code = UnicodeString(strip=True, min=1, not_empty=False)
238 rhodecode_ga_code = v.UnicodeString(strip=True, min=1, not_empty=False)
723
239
724 return _ApplicationSettingsForm
240 return _ApplicationSettingsForm
725
241
@@ -728,12 +244,19 b' def ApplicationUiSettingsForm():'
728 class _ApplicationUiSettingsForm(formencode.Schema):
244 class _ApplicationUiSettingsForm(formencode.Schema):
729 allow_extra_fields = True
245 allow_extra_fields = True
730 filter_extra_fields = False
246 filter_extra_fields = False
731 web_push_ssl = OneOf(['true', 'false'], if_missing='false')
247 web_push_ssl = v.OneOf(['true', 'false'], if_missing='false')
732 paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=1, not_empty=True))
248 paths_root_path = All(
733 hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False)
249 v.ValidPath(),
734 hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False)
250 v.UnicodeString(strip=True, min=1, not_empty=True)
735 hooks_changegroup_push_logger = OneOf(['True', 'False'], if_missing=False)
251 )
736 hooks_preoutgoing_pull_logger = OneOf(['True', 'False'], if_missing=False)
252 hooks_changegroup_update = v.OneOf(['True', 'False'],
253 if_missing=False)
254 hooks_changegroup_repo_size = v.OneOf(['True', 'False'],
255 if_missing=False)
256 hooks_changegroup_push_logger = v.OneOf(['True', 'False'],
257 if_missing=False)
258 hooks_preoutgoing_pull_logger = v.OneOf(['True', 'False'],
259 if_missing=False)
737
260
738 return _ApplicationUiSettingsForm
261 return _ApplicationUiSettingsForm
739
262
@@ -742,33 +265,37 b' def DefaultPermissionsForm(perms_choices'
742 class _DefaultPermissionsForm(formencode.Schema):
265 class _DefaultPermissionsForm(formencode.Schema):
743 allow_extra_fields = True
266 allow_extra_fields = True
744 filter_extra_fields = True
267 filter_extra_fields = True
745 overwrite_default = StringBoolean(if_missing=False)
268 overwrite_default = v.StringBoolean(if_missing=False)
746 anonymous = OneOf(['True', 'False'], if_missing=False)
269 anonymous = v.OneOf(['True', 'False'], if_missing=False)
747 default_perm = OneOf(perms_choices)
270 default_perm = v.OneOf(perms_choices)
748 default_register = OneOf(register_choices)
271 default_register = v.OneOf(register_choices)
749 default_create = OneOf(create_choices)
272 default_create = v.OneOf(create_choices)
750
273
751 return _DefaultPermissionsForm
274 return _DefaultPermissionsForm
752
275
753
276
754 def LdapSettingsForm(tls_reqcert_choices, search_scope_choices, tls_kind_choices):
277 def LdapSettingsForm(tls_reqcert_choices, search_scope_choices,
278 tls_kind_choices):
755 class _LdapSettingsForm(formencode.Schema):
279 class _LdapSettingsForm(formencode.Schema):
756 allow_extra_fields = True
280 allow_extra_fields = True
757 filter_extra_fields = True
281 filter_extra_fields = True
758 #pre_validators = [LdapLibValidator]
282 #pre_validators = [LdapLibValidator]
759 ldap_active = StringBoolean(if_missing=False)
283 ldap_active = v.StringBoolean(if_missing=False)
760 ldap_host = UnicodeString(strip=True,)
284 ldap_host = v.UnicodeString(strip=True,)
761 ldap_port = Number(strip=True,)
285 ldap_port = v.Number(strip=True,)
762 ldap_tls_kind = OneOf(tls_kind_choices)
286 ldap_tls_kind = v.OneOf(tls_kind_choices)
763 ldap_tls_reqcert = OneOf(tls_reqcert_choices)
287 ldap_tls_reqcert = v.OneOf(tls_reqcert_choices)
764 ldap_dn_user = UnicodeString(strip=True,)
288 ldap_dn_user = v.UnicodeString(strip=True,)
765 ldap_dn_pass = UnicodeString(strip=True,)
289 ldap_dn_pass = v.UnicodeString(strip=True,)
766 ldap_base_dn = UnicodeString(strip=True,)
290 ldap_base_dn = v.UnicodeString(strip=True,)
767 ldap_filter = UnicodeString(strip=True,)
291 ldap_filter = v.UnicodeString(strip=True,)
768 ldap_search_scope = OneOf(search_scope_choices)
292 ldap_search_scope = v.OneOf(search_scope_choices)
769 ldap_attr_login = All(AttrLoginValidator, UnicodeString(strip=True,))
293 ldap_attr_login = All(
770 ldap_attr_firstname = UnicodeString(strip=True,)
294 v.AttrLoginValidator(),
771 ldap_attr_lastname = UnicodeString(strip=True,)
295 v.UnicodeString(strip=True,)
772 ldap_attr_email = UnicodeString(strip=True,)
296 )
297 ldap_attr_firstname = v.UnicodeString(strip=True,)
298 ldap_attr_lastname = v.UnicodeString(strip=True,)
299 ldap_attr_email = v.UnicodeString(strip=True,)
773
300
774 return _LdapSettingsForm
301 return _LdapSettingsForm
@@ -199,13 +199,13 b' class ReposGroupModel(BaseModel):'
199 log.error(traceback.format_exc())
199 log.error(traceback.format_exc())
200 raise
200 raise
201
201
202 def delete(self, users_group_id):
202 def delete(self, repos_group):
203 repos_group = self.__get_repos_group(repos_group)
203 try:
204 try:
204 users_group = RepoGroup.get(users_group_id)
205 self.sa.delete(repos_group)
205 self.sa.delete(users_group)
206 self.__delete_group(repos_group)
206 self.__delete_group(users_group)
207 except:
207 except:
208 log.error(traceback.format_exc())
208 log.exception('Error removing repos_group %s' % repos_group)
209 raise
209 raise
210
210
211 def grant_user_permission(self, repos_group, user, perm):
211 def grant_user_permission(self, repos_group, user, perm):
@@ -87,9 +87,12 b' class UserModel(BaseModel):'
87 return User.get_by_api_key(api_key, cache)
87 return User.get_by_api_key(api_key, cache)
88
88
89 def create(self, form_data):
89 def create(self, form_data):
90 from rhodecode.lib.auth import get_crypt_password
90 try:
91 try:
91 new_user = User()
92 new_user = User()
92 for k, v in form_data.items():
93 for k, v in form_data.items():
94 if k == 'password':
95 v = get_crypt_password(v)
93 setattr(new_user, k, v)
96 setattr(new_user, k, v)
94
97
95 new_user.api_key = generate_api_key(form_data['username'])
98 new_user.api_key = generate_api_key(form_data['username'])
@@ -265,15 +268,17 b' class UserModel(BaseModel):'
265 raise
268 raise
266
269
267 def update_my_account(self, user_id, form_data):
270 def update_my_account(self, user_id, form_data):
271 from rhodecode.lib.auth import get_crypt_password
268 try:
272 try:
269 user = self.get(user_id, cache=False)
273 user = self.get(user_id, cache=False)
270 if user.username == 'default':
274 if user.username == 'default':
271 raise DefaultUserException(
275 raise DefaultUserException(
272 _("You can't Edit this user since it's"
276 _("You can't Edit this user since it's"
273 " crucial for entire application"))
277 " crucial for entire application")
278 )
274 for k, v in form_data.items():
279 for k, v in form_data.items():
275 if k == 'new_password' and v != '':
280 if k == 'new_password' and v != '':
276 user.password = v
281 user.password = get_crypt_password(v)
277 user.api_key = generate_api_key(user.username)
282 user.api_key = generate_api_key(user.username)
278 else:
283 else:
279 if k not in ['admin', 'active']:
284 if k not in ['admin', 'active']:
@@ -3,6 +3,8 b''
3 from rhodecode.lib.auth import get_crypt_password, check_password
3 from rhodecode.lib.auth import get_crypt_password, check_password
4 from rhodecode.model.db import User, RhodeCodeSetting
4 from rhodecode.model.db import User, RhodeCodeSetting
5 from rhodecode.tests import *
5 from rhodecode.tests import *
6 from rhodecode.lib import helpers as h
7
6
8
7 class TestAdminSettingsController(TestController):
9 class TestAdminSettingsController(TestController):
8
10
@@ -47,7 +49,6 b' class TestAdminSettingsController(TestCo'
47 response = self.app.get(url('formatted_admin_edit_setting',
49 response = self.app.get(url('formatted_admin_edit_setting',
48 setting_id=1, format='xml'))
50 setting_id=1, format='xml'))
49
51
50
51 def test_ga_code_active(self):
52 def test_ga_code_active(self):
52 self.log_user()
53 self.log_user()
53 old_title = 'RhodeCode'
54 old_title = 'RhodeCode'
@@ -92,7 +93,6 b' class TestAdminSettingsController(TestCo'
92 self.assertTrue("""_gaq.push(['_setAccount', '%s']);""" % new_ga_code
93 self.assertTrue("""_gaq.push(['_setAccount', '%s']);""" % new_ga_code
93 not in response.body)
94 not in response.body)
94
95
95
96 def test_title_change(self):
96 def test_title_change(self):
97 self.log_user()
97 self.log_user()
98 old_title = 'RhodeCode'
98 old_title = 'RhodeCode'
@@ -117,7 +117,6 b' class TestAdminSettingsController(TestCo'
117 self.assertTrue("""<h1><a href="/">%s</a></h1>""" % new_title
117 self.assertTrue("""<h1><a href="/">%s</a></h1>""" % new_title
118 in response.body)
118 in response.body)
119
119
120
121 def test_my_account(self):
120 def test_my_account(self):
122 self.log_user()
121 self.log_user()
123 response = self.app.get(url('admin_settings_my_account'))
122 response = self.app.get(url('admin_settings_my_account'))
@@ -132,12 +131,11 b' class TestAdminSettingsController(TestCo'
132 new_lastname = 'NewLastname'
131 new_lastname = 'NewLastname'
133 new_password = 'test123'
132 new_password = 'test123'
134
133
135
136 response = self.app.post(url('admin_settings_my_account_update'),
134 response = self.app.post(url('admin_settings_my_account_update'),
137 params=dict(_method='put',
135 params=dict(_method='put',
138 username='test_admin',
136 username='test_admin',
139 new_password=new_password,
137 new_password=new_password,
140 password_confirmation = new_password,
138 password_confirmation=new_password,
141 password='',
139 password='',
142 name=new_name,
140 name=new_name,
143 lastname=new_lastname,
141 lastname=new_lastname,
@@ -146,7 +144,7 b' class TestAdminSettingsController(TestCo'
146
144
147 assert 'Your account was updated successfully' in response.session['flash'][0][1], 'no flash message about success of change'
145 assert 'Your account was updated successfully' in response.session['flash'][0][1], 'no flash message about success of change'
148 user = self.Session.query(User).filter(User.username == 'test_admin').one()
146 user = self.Session.query(User).filter(User.username == 'test_admin').one()
149 assert user.email == new_email , 'incorrect user email after update got %s vs %s' % (user.email, new_email)
147 assert user.email == new_email, 'incorrect user email after update got %s vs %s' % (user.email, new_email)
150 assert user.name == new_name, 'updated field mismatch %s vs %s' % (user.name, new_name)
148 assert user.name == new_name, 'updated field mismatch %s vs %s' % (user.name, new_name)
151 assert user.lastname == new_lastname, 'updated field mismatch %s vs %s' % (user.lastname, new_lastname)
149 assert user.lastname == new_lastname, 'updated field mismatch %s vs %s' % (user.lastname, new_lastname)
152 assert check_password(new_password, user.password) is True, 'password field mismatch %s vs %s' % (user.password, new_password)
150 assert check_password(new_password, user.password) is True, 'password field mismatch %s vs %s' % (user.password, new_password)
@@ -161,7 +159,7 b' class TestAdminSettingsController(TestCo'
161 _method='put',
159 _method='put',
162 username='test_admin',
160 username='test_admin',
163 new_password=old_password,
161 new_password=old_password,
164 password_confirmation = old_password,
162 password_confirmation=old_password,
165 password='',
163 password='',
166 name=old_name,
164 name=old_name,
167 lastname=old_lastname,
165 lastname=old_lastname,
@@ -172,41 +170,46 b' class TestAdminSettingsController(TestCo'
172 'Your account was updated successfully')
170 'Your account was updated successfully')
173
171
174 user = self.Session.query(User).filter(User.username == 'test_admin').one()
172 user = self.Session.query(User).filter(User.username == 'test_admin').one()
175 assert user.email == old_email , 'incorrect user email after update got %s vs %s' % (user.email, old_email)
173 assert user.email == old_email, 'incorrect user email after update got %s vs %s' % (user.email, old_email)
176
174
177 assert user.email == old_email , 'incorrect user email after update got %s vs %s' % (user.email, old_email)
175 assert user.email == old_email, 'incorrect user email after update got %s vs %s' % (user.email, old_email)
178 assert user.name == old_name, 'updated field mismatch %s vs %s' % (user.name, old_name)
176 assert user.name == old_name, 'updated field mismatch %s vs %s' % (user.name, old_name)
179 assert user.lastname == old_lastname, 'updated field mismatch %s vs %s' % (user.lastname, old_lastname)
177 assert user.lastname == old_lastname, 'updated field mismatch %s vs %s' % (user.lastname, old_lastname)
180 assert check_password(old_password, user.password) is True , 'password updated field mismatch %s vs %s' % (user.password, old_password)
178 assert check_password(old_password, user.password) is True, 'password updated field mismatch %s vs %s' % (user.password, old_password)
181
182
179
183 def test_my_account_update_err_email_exists(self):
180 def test_my_account_update_err_email_exists(self):
184 self.log_user()
181 self.log_user()
185
182
186 new_email = 'test_regular@mail.com'#already exisitn email
183 new_email = 'test_regular@mail.com' # already exisitn email
187 response = self.app.post(url('admin_settings_my_account_update'), params=dict(
184 response = self.app.post(url('admin_settings_my_account_update'), params=dict(
188 _method='put',
185 _method='put',
189 username='test_admin',
186 username='test_admin',
190 new_password='test12',
187 new_password='test12',
191 password_confirmation = 'test122',
188 password_confirmation='test122',
192 name='NewName',
189 name='NewName',
193 lastname='NewLastname',
190 lastname='NewLastname',
194 email=new_email,))
191 email=new_email,))
195
192
196 assert 'This e-mail address is already taken' in response.body, 'Missing error message about existing email'
193 assert 'This e-mail address is already taken' in response.body, 'Missing error message about existing email'
197
194
198
199 def test_my_account_update_err(self):
195 def test_my_account_update_err(self):
200 self.log_user('test_regular2', 'test12')
196 self.log_user('test_regular2', 'test12')
201
197
202 new_email = 'newmail.pl'
198 new_email = 'newmail.pl'
203 response = self.app.post(url('admin_settings_my_account_update'), params=dict(
199 response = self.app.post(url('admin_settings_my_account_update'),
204 _method='put',
200 params=dict(
205 username='test_admin',
201 _method='put',
206 new_password='test12',
202 username='test_admin',
207 password_confirmation = 'test122',
203 new_password='test12',
208 name='NewName',
204 password_confirmation='test122',
209 lastname='NewLastname',
205 name='NewName',
210 email=new_email,))
206 lastname='NewLastname',
211 assert 'An email address must contain a single @' in response.body, 'Missing error message about wrong email'
207 email=new_email,)
212 assert 'This username already exists' in response.body, 'Missing error message about existing user'
208 )
209
210 response.mustcontain('An email address must contain a single @')
211 from rhodecode.model import validators
212 msg = validators.ValidUsername(edit=False,
213 old_data={})._messages['username_exists']
214 msg = h.html_escape(msg % {'username': 'test_admin'})
215 response.mustcontain(u"%s" % msg)
@@ -1,8 +1,12 b''
1 from sqlalchemy.orm.exc import NoResultFound
2
1 from rhodecode.tests import *
3 from rhodecode.tests import *
2 from rhodecode.model.db import User, Permission
4 from rhodecode.model.db import User, Permission
3 from rhodecode.lib.auth import check_password
5 from rhodecode.lib.auth import check_password
4 from sqlalchemy.orm.exc import NoResultFound
5 from rhodecode.model.user import UserModel
6 from rhodecode.model.user import UserModel
7 from rhodecode.model import validators
8 from rhodecode.lib import helpers as h
9
6
10
7 class TestAdminUsersController(TestController):
11 class TestAdminUsersController(TestController):
8
12
@@ -24,26 +28,25 b' class TestAdminUsersController(TestContr'
24 email = 'mail@mail.com'
28 email = 'mail@mail.com'
25
29
26 response = self.app.post(url('users'),
30 response = self.app.post(url('users'),
27 {'username':username,
31 {'username': username,
28 'password':password,
32 'password': password,
29 'password_confirmation':password_confirmation,
33 'password_confirmation': password_confirmation,
30 'name':name,
34 'name': name,
31 'active':True,
35 'active': True,
32 'lastname':lastname,
36 'lastname': lastname,
33 'email':email})
37 'email': email})
34
38
39 self.checkSessionFlash(response, '''created user %s''' % (username))
35
40
36 self.assertTrue('''created user %s''' % (username) in
37 response.session['flash'][0])
38
41
39 new_user = self.Session.query(User).\
42 new_user = self.Session.query(User).\
40 filter(User.username == username).one()
43 filter(User.username == username).one()
41
44
42 self.assertEqual(new_user.username,username)
45 self.assertEqual(new_user.username, username)
43 self.assertEqual(check_password(password, new_user.password),True)
46 self.assertEqual(check_password(password, new_user.password), True)
44 self.assertEqual(new_user.name,name)
47 self.assertEqual(new_user.name, name)
45 self.assertEqual(new_user.lastname,lastname)
48 self.assertEqual(new_user.lastname, lastname)
46 self.assertEqual(new_user.email,email)
49 self.assertEqual(new_user.email, email)
47
50
48 response.follow()
51 response.follow()
49 response = response.follow()
52 response = response.follow()
@@ -57,16 +60,18 b' class TestAdminUsersController(TestContr'
57 lastname = 'lastname'
60 lastname = 'lastname'
58 email = 'errmail.com'
61 email = 'errmail.com'
59
62
60 response = self.app.post(url('users'), {'username':username,
63 response = self.app.post(url('users'), {'username': username,
61 'password':password,
64 'password': password,
62 'name':name,
65 'name': name,
63 'active':False,
66 'active': False,
64 'lastname':lastname,
67 'lastname': lastname,
65 'email':email})
68 'email': email})
66
69
67 self.assertTrue("""<span class="error-message">Invalid username</span>""" in response.body)
70 msg = validators.ValidUsername(False, {})._messages['system_invalid_username']
68 self.assertTrue("""<span class="error-message">Please enter a value</span>""" in response.body)
71 msg = h.html_escape(msg % {'username': 'new_user'})
69 self.assertTrue("""<span class="error-message">An email address must contain a single @</span>""" in response.body)
72 response.mustcontain("""<span class="error-message">%s</span>""" % msg)
73 response.mustcontain("""<span class="error-message">Please enter a value</span>""")
74 response.mustcontain("""<span class="error-message">An email address must contain a single @</span>""")
70
75
71 def get_user():
76 def get_user():
72 self.Session.query(User).filter(User.username == username).one()
77 self.Session.query(User).filter(User.username == username).one()
@@ -94,13 +99,13 b' class TestAdminUsersController(TestContr'
94 lastname = 'lastname'
99 lastname = 'lastname'
95 email = 'todeletemail@mail.com'
100 email = 'todeletemail@mail.com'
96
101
97 response = self.app.post(url('users'), {'username':username,
102 response = self.app.post(url('users'), {'username': username,
98 'password':password,
103 'password': password,
99 'password_confirmation':password,
104 'password_confirmation': password,
100 'name':name,
105 'name': name,
101 'active':True,
106 'active': True,
102 'lastname':lastname,
107 'lastname': lastname,
103 'email':email})
108 'email': email})
104
109
105 response = response.follow()
110 response = response.follow()
106
111
@@ -111,7 +116,6 b' class TestAdminUsersController(TestContr'
111 self.assertTrue("""successfully deleted user""" in
116 self.assertTrue("""successfully deleted user""" in
112 response.session['flash'][0])
117 response.session['flash'][0])
113
118
114
115 def test_delete_browser_fakeout(self):
119 def test_delete_browser_fakeout(self):
116 response = self.app.post(url('user', id=1),
120 response = self.app.post(url('user', id=1),
117 params=dict(_method='delete'))
121 params=dict(_method='delete'))
@@ -127,7 +131,6 b' class TestAdminUsersController(TestContr'
127 user = User.get_by_username(TEST_USER_ADMIN_LOGIN)
131 user = User.get_by_username(TEST_USER_ADMIN_LOGIN)
128 response = self.app.get(url('edit_user', id=user.user_id))
132 response = self.app.get(url('edit_user', id=user.user_id))
129
133
130
131 def test_add_perm_create_repo(self):
134 def test_add_perm_create_repo(self):
132 self.log_user()
135 self.log_user()
133 perm_none = Permission.get_by_key('hg.create.none')
136 perm_none = Permission.get_by_key('hg.create.none')
@@ -135,7 +138,6 b' class TestAdminUsersController(TestContr'
135
138
136 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
139 user = User.get_by_username(TEST_USER_REGULAR_LOGIN)
137
140
138
139 #User should have None permission on creation repository
141 #User should have None permission on creation repository
140 self.assertEqual(UserModel().has_perm(user, perm_none), False)
142 self.assertEqual(UserModel().has_perm(user, perm_none), False)
141 self.assertEqual(UserModel().has_perm(user, perm_create), False)
143 self.assertEqual(UserModel().has_perm(user, perm_create), False)
@@ -159,7 +161,6 b' class TestAdminUsersController(TestContr'
159
161
160 user = User.get_by_username(TEST_USER_REGULAR2_LOGIN)
162 user = User.get_by_username(TEST_USER_REGULAR2_LOGIN)
161
163
162
163 #User should have None permission on creation repository
164 #User should have None permission on creation repository
164 self.assertEqual(UserModel().has_perm(user, perm_none), False)
165 self.assertEqual(UserModel().has_perm(user, perm_none), False)
165 self.assertEqual(UserModel().has_perm(user, perm_create), False)
166 self.assertEqual(UserModel().has_perm(user, perm_create), False)
@@ -4,6 +4,8 b' from rhodecode.model.db import User, Not'
4 from rhodecode.lib.utils2 import generate_api_key
4 from rhodecode.lib.utils2 import generate_api_key
5 from rhodecode.lib.auth import check_password
5 from rhodecode.lib.auth import check_password
6 from rhodecode.model.meta import Session
6 from rhodecode.model.meta import Session
7 from rhodecode.lib import helpers as h
8 from rhodecode.model import validators
7
9
8
10
9 class TestLoginController(TestController):
11 class TestLoginController(TestController):
@@ -22,21 +24,21 b' class TestLoginController(TestController'
22
24
23 def test_login_admin_ok(self):
25 def test_login_admin_ok(self):
24 response = self.app.post(url(controller='login', action='index'),
26 response = self.app.post(url(controller='login', action='index'),
25 {'username':'test_admin',
27 {'username': 'test_admin',
26 'password':'test12'})
28 'password': 'test12'})
27 self.assertEqual(response.status, '302 Found')
29 self.assertEqual(response.status, '302 Found')
28 self.assertEqual(response.session['rhodecode_user'].get('username') ,
30 self.assertEqual(response.session['rhodecode_user'].get('username'),
29 'test_admin')
31 'test_admin')
30 response = response.follow()
32 response = response.follow()
31 self.assertTrue('%s repository' % HG_REPO in response.body)
33 self.assertTrue('%s repository' % HG_REPO in response.body)
32
34
33 def test_login_regular_ok(self):
35 def test_login_regular_ok(self):
34 response = self.app.post(url(controller='login', action='index'),
36 response = self.app.post(url(controller='login', action='index'),
35 {'username':'test_regular',
37 {'username': 'test_regular',
36 'password':'test12'})
38 'password': 'test12'})
37
39
38 self.assertEqual(response.status, '302 Found')
40 self.assertEqual(response.status, '302 Found')
39 self.assertEqual(response.session['rhodecode_user'].get('username') ,
41 self.assertEqual(response.session['rhodecode_user'].get('username'),
40 'test_regular')
42 'test_regular')
41 response = response.follow()
43 response = response.follow()
42 self.assertTrue('%s repository' % HG_REPO in response.body)
44 self.assertTrue('%s repository' % HG_REPO in response.body)
@@ -46,8 +48,8 b' class TestLoginController(TestController'
46 test_came_from = '/_admin/users'
48 test_came_from = '/_admin/users'
47 response = self.app.post(url(controller='login', action='index',
49 response = self.app.post(url(controller='login', action='index',
48 came_from=test_came_from),
50 came_from=test_came_from),
49 {'username':'test_admin',
51 {'username': 'test_admin',
50 'password':'test12'})
52 'password': 'test12'})
51 self.assertEqual(response.status, '302 Found')
53 self.assertEqual(response.status, '302 Found')
52 response = response.follow()
54 response = response.follow()
53
55
@@ -56,17 +58,16 b' class TestLoginController(TestController'
56
58
57 def test_login_short_password(self):
59 def test_login_short_password(self):
58 response = self.app.post(url(controller='login', action='index'),
60 response = self.app.post(url(controller='login', action='index'),
59 {'username':'test_admin',
61 {'username': 'test_admin',
60 'password':'as'})
62 'password': 'as'})
61 self.assertEqual(response.status, '200 OK')
63 self.assertEqual(response.status, '200 OK')
62
64
63 self.assertTrue('Enter 3 characters or more' in response.body)
65 self.assertTrue('Enter 3 characters or more' in response.body)
64
66
65 def test_login_wrong_username_password(self):
67 def test_login_wrong_username_password(self):
66 response = self.app.post(url(controller='login', action='index'),
68 response = self.app.post(url(controller='login', action='index'),
67 {'username':'error',
69 {'username': 'error',
68 'password':'test12'})
70 'password': 'test12'})
69 self.assertEqual(response.status , '200 OK')
70
71
71 self.assertTrue('invalid user name' in response.body)
72 self.assertTrue('invalid user name' in response.body)
72 self.assertTrue('invalid password' in response.body)
73 self.assertTrue('invalid password' in response.body)
@@ -79,62 +80,63 b' class TestLoginController(TestController'
79 self.assertTrue('Sign Up to RhodeCode' in response.body)
80 self.assertTrue('Sign Up to RhodeCode' in response.body)
80
81
81 def test_register_err_same_username(self):
82 def test_register_err_same_username(self):
83 uname = 'test_admin'
82 response = self.app.post(url(controller='login', action='register'),
84 response = self.app.post(url(controller='login', action='register'),
83 {'username':'test_admin',
85 {'username': uname,
84 'password':'test12',
86 'password': 'test12',
85 'password_confirmation':'test12',
87 'password_confirmation': 'test12',
86 'email':'goodmail@domain.com',
88 'email': 'goodmail@domain.com',
87 'name':'test',
89 'name': 'test',
88 'lastname':'test'})
90 'lastname': 'test'})
89
91
90 self.assertEqual(response.status , '200 OK')
92 msg = validators.ValidUsername()._messages['username_exists']
91 self.assertTrue('This username already exists' in response.body)
93 msg = h.html_escape(msg % {'username': uname})
94 response.mustcontain(msg)
92
95
93 def test_register_err_same_email(self):
96 def test_register_err_same_email(self):
94 response = self.app.post(url(controller='login', action='register'),
97 response = self.app.post(url(controller='login', action='register'),
95 {'username':'test_admin_0',
98 {'username': 'test_admin_0',
96 'password':'test12',
99 'password': 'test12',
97 'password_confirmation':'test12',
100 'password_confirmation': 'test12',
98 'email':'test_admin@mail.com',
101 'email': 'test_admin@mail.com',
99 'name':'test',
102 'name': 'test',
100 'lastname':'test'})
103 'lastname': 'test'})
101
104
102 self.assertEqual(response.status , '200 OK')
105 msg = validators.UniqSystemEmail()()._messages['email_taken']
103 response.mustcontain('This e-mail address is already taken')
106 response.mustcontain(msg)
104
107
105 def test_register_err_same_email_case_sensitive(self):
108 def test_register_err_same_email_case_sensitive(self):
106 response = self.app.post(url(controller='login', action='register'),
109 response = self.app.post(url(controller='login', action='register'),
107 {'username':'test_admin_1',
110 {'username': 'test_admin_1',
108 'password':'test12',
111 'password': 'test12',
109 'password_confirmation':'test12',
112 'password_confirmation': 'test12',
110 'email':'TesT_Admin@mail.COM',
113 'email': 'TesT_Admin@mail.COM',
111 'name':'test',
114 'name': 'test',
112 'lastname':'test'})
115 'lastname': 'test'})
113 self.assertEqual(response.status , '200 OK')
116 msg = validators.UniqSystemEmail()()._messages['email_taken']
114 response.mustcontain('This e-mail address is already taken')
117 response.mustcontain(msg)
115
118
116 def test_register_err_wrong_data(self):
119 def test_register_err_wrong_data(self):
117 response = self.app.post(url(controller='login', action='register'),
120 response = self.app.post(url(controller='login', action='register'),
118 {'username':'xs',
121 {'username': 'xs',
119 'password':'test',
122 'password': 'test',
120 'password_confirmation':'test',
123 'password_confirmation': 'test',
121 'email':'goodmailm',
124 'email': 'goodmailm',
122 'name':'test',
125 'name': 'test',
123 'lastname':'test'})
126 'lastname': 'test'})
124 self.assertEqual(response.status , '200 OK')
127 self.assertEqual(response.status, '200 OK')
125 response.mustcontain('An email address must contain a single @')
128 response.mustcontain('An email address must contain a single @')
126 response.mustcontain('Enter a value 6 characters long or more')
129 response.mustcontain('Enter a value 6 characters long or more')
127
130
128 def test_register_err_username(self):
131 def test_register_err_username(self):
129 response = self.app.post(url(controller='login', action='register'),
132 response = self.app.post(url(controller='login', action='register'),
130 {'username':'error user',
133 {'username': 'error user',
131 'password':'test12',
134 'password': 'test12',
132 'password_confirmation':'test12',
135 'password_confirmation': 'test12',
133 'email':'goodmailm',
136 'email': 'goodmailm',
134 'name':'test',
137 'name': 'test',
135 'lastname':'test'})
138 'lastname': 'test'})
136
139
137 self.assertEqual(response.status , '200 OK')
138 response.mustcontain('An email address must contain a single @')
140 response.mustcontain('An email address must contain a single @')
139 response.mustcontain('Username may only contain '
141 response.mustcontain('Username may only contain '
140 'alphanumeric characters underscores, '
142 'alphanumeric characters underscores, '
@@ -142,41 +144,42 b' class TestLoginController(TestController'
142 'alphanumeric character')
144 'alphanumeric character')
143
145
144 def test_register_err_case_sensitive(self):
146 def test_register_err_case_sensitive(self):
147 usr = 'Test_Admin'
145 response = self.app.post(url(controller='login', action='register'),
148 response = self.app.post(url(controller='login', action='register'),
146 {'username':'Test_Admin',
149 {'username': usr,
147 'password':'test12',
150 'password': 'test12',
148 'password_confirmation':'test12',
151 'password_confirmation': 'test12',
149 'email':'goodmailm',
152 'email': 'goodmailm',
150 'name':'test',
153 'name': 'test',
151 'lastname':'test'})
154 'lastname': 'test'})
152
155
153 self.assertEqual(response.status , '200 OK')
156 response.mustcontain('An email address must contain a single @')
154 self.assertTrue('An email address must contain a single @' in response.body)
157 msg = validators.ValidUsername()._messages['username_exists']
155 self.assertTrue('This username already exists' in response.body)
158 msg = h.html_escape(msg % {'username': usr})
159 response.mustcontain(msg)
156
160
157 def test_register_special_chars(self):
161 def test_register_special_chars(self):
158 response = self.app.post(url(controller='login', action='register'),
162 response = self.app.post(url(controller='login', action='register'),
159 {'username':'xxxaxn',
163 {'username': 'xxxaxn',
160 'password':'Δ…Δ‡ΕΊΕΌΔ…Ε›Ε›Ε›Ε›',
164 'password': 'Δ…Δ‡ΕΊΕΌΔ…Ε›Ε›Ε›Ε›',
161 'password_confirmation':'Δ…Δ‡ΕΊΕΌΔ…Ε›Ε›Ε›Ε›',
165 'password_confirmation': 'Δ…Δ‡ΕΊΕΌΔ…Ε›Ε›Ε›Ε›',
162 'email':'goodmailm@test.plx',
166 'email': 'goodmailm@test.plx',
163 'name':'test',
167 'name': 'test',
164 'lastname':'test'})
168 'lastname': 'test'})
165
169
166 self.assertEqual(response.status , '200 OK')
170 msg = validators.ValidPassword()._messages['invalid_password']
167 self.assertTrue('Invalid characters in password' in response.body)
171 response.mustcontain(msg)
168
172
169 def test_register_password_mismatch(self):
173 def test_register_password_mismatch(self):
170 response = self.app.post(url(controller='login', action='register'),
174 response = self.app.post(url(controller='login', action='register'),
171 {'username':'xs',
175 {'username': 'xs',
172 'password':'123qwe',
176 'password': '123qwe',
173 'password_confirmation':'qwe123',
177 'password_confirmation': 'qwe123',
174 'email':'goodmailm@test.plxa',
178 'email': 'goodmailm@test.plxa',
175 'name':'test',
179 'name': 'test',
176 'lastname':'test'})
180 'lastname': 'test'})
177
181 msg = validators.ValidPasswordsMatch()._messages['password_mismatch']
178 self.assertEqual(response.status, '200 OK')
182 response.mustcontain(msg)
179 response.mustcontain('Passwords do not match')
180
183
181 def test_register_ok(self):
184 def test_register_ok(self):
182 username = 'test_regular4'
185 username = 'test_regular4'
@@ -186,13 +189,13 b' class TestLoginController(TestController'
186 lastname = 'testlastname'
189 lastname = 'testlastname'
187
190
188 response = self.app.post(url(controller='login', action='register'),
191 response = self.app.post(url(controller='login', action='register'),
189 {'username':username,
192 {'username': username,
190 'password':password,
193 'password': password,
191 'password_confirmation':password,
194 'password_confirmation': password,
192 'email':email,
195 'email': email,
193 'name':name,
196 'name': name,
194 'lastname':lastname,
197 'lastname': lastname,
195 'admin':True}) # This should be overriden
198 'admin': True}) # This should be overriden
196 self.assertEqual(response.status, '302 Found')
199 self.assertEqual(response.status, '302 Found')
197 self.checkSessionFlash(response, 'You have successfully registered into rhodecode')
200 self.checkSessionFlash(response, 'You have successfully registered into rhodecode')
198
201
@@ -206,12 +209,15 b' class TestLoginController(TestController'
206 self.assertEqual(ret.admin, False)
209 self.assertEqual(ret.admin, False)
207
210
208 def test_forgot_password_wrong_mail(self):
211 def test_forgot_password_wrong_mail(self):
212 bad_email = 'marcin@wrongmail.org'
209 response = self.app.post(
213 response = self.app.post(
210 url(controller='login', action='password_reset'),
214 url(controller='login', action='password_reset'),
211 {'email': 'marcin@wrongmail.org',}
215 {'email': bad_email, }
212 )
216 )
213
217
214 response.mustcontain("This e-mail address doesn't exist")
218 msg = validators.ValidSystemEmail()._messages['non_existing_email']
219 msg = h.html_escape(msg % {'email': bad_email})
220 response.mustcontain()
215
221
216 def test_forgot_password(self):
222 def test_forgot_password(self):
217 response = self.app.get(url(controller='login',
223 response = self.app.get(url(controller='login',
@@ -236,7 +242,7 b' class TestLoginController(TestController'
236
242
237 response = self.app.post(url(controller='login',
243 response = self.app.post(url(controller='login',
238 action='password_reset'),
244 action='password_reset'),
239 {'email':email, })
245 {'email': email, })
240
246
241 self.checkSessionFlash(response, 'Your password reset link was sent')
247 self.checkSessionFlash(response, 'Your password reset link was sent')
242
248
General Comments 0
You need to be logged in to leave comments. Login now