Show More
@@ -220,7 +220,7 b' class UsersController(BaseController):' | |||
|
220 | 220 | return redirect(url('edit_user', id=id)) |
|
221 | 221 | |
|
222 | 222 | def add_email(self, id): |
|
223 |
"""P |
|
|
223 | """POST /user_emails:Add an existing item""" | |
|
224 | 224 | # url('user_emails', id=ID, method='put') |
|
225 | 225 | |
|
226 | 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 | 19 | for SELECT use formencode.All(OneOf(list), Int()) |
|
20 | 20 | |
|
21 | 21 | """ |
|
22 | import os | |
|
23 | import re | |
|
24 | 22 | import logging |
|
25 | import traceback | |
|
26 | 23 | |
|
27 | 24 | import formencode |
|
28 | 25 | from formencode import All |
|
29 | from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \ | |
|
30 | Email, Bool, StringBoolean, Set | |
|
31 | 26 | |
|
32 | 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 | |
|
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 | |
|
29 | from rhodecode.model import validators as v | |
|
40 | 30 | from rhodecode import BACKENDS |
|
41 | 31 | |
|
42 | 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 | 35 | class LoginForm(formencode.Schema): |
|
542 | 36 | allow_extra_fields = True |
|
543 | 37 | filter_extra_fields = True |
|
544 | username = UnicodeString( | |
|
38 | username = v.UnicodeString( | |
|
545 | 39 | strip=True, |
|
546 | 40 | min=1, |
|
547 | 41 | not_empty=True, |
|
548 | 42 | messages={ |
|
549 | 'empty': _('Please enter a login'), | |
|
550 | 'tooShort': _('Enter a value %(min)i characters long or more')} | |
|
43 | 'empty': _(u'Please enter a login'), | |
|
44 | 'tooShort': _(u'Enter a value %(min)i characters long or more')} | |
|
551 | 45 | ) |
|
552 | 46 | |
|
553 | password = UnicodeString( | |
|
47 | password = v.UnicodeString( | |
|
554 | 48 | strip=False, |
|
555 | 49 | min=3, |
|
556 | 50 | not_empty=True, |
|
557 | 51 | messages={ |
|
558 | 'empty': _('Please enter a password'), | |
|
559 | 'tooShort': _('Enter %(min)i characters or more')} | |
|
52 | 'empty': _(u'Please enter a password'), | |
|
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 | 61 | def UserForm(edit=False, old_data={}): |
|
568 | 62 | class _UserForm(formencode.Schema): |
|
569 | 63 | allow_extra_fields = True |
|
570 | 64 | filter_extra_fields = True |
|
571 | username = All(UnicodeString(strip=True, min=1, not_empty=True), | |
|
572 | ValidUsername(edit, old_data)) | |
|
65 | username = All(v.UnicodeString(strip=True, min=1, not_empty=True), | |
|
66 | v.ValidUsername(edit, old_data)) | |
|
573 | 67 | if edit: |
|
574 | new_password = All(UnicodeString(strip=False, min=6, not_empty=False)) | |
|
575 |
|
|
|
576 | not_empty=False)) | |
|
577 | admin = StringBoolean(if_missing=False) | |
|
68 | new_password = All( | |
|
69 | v.UnicodeString(strip=False, min=6, not_empty=False) | |
|
70 | ) | |
|
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 | 76 | else: |
|
579 | password = All(UnicodeString(strip=False, min=6, not_empty=True)) | |
|
580 | password_confirmation = All(UnicodeString(strip=False, min=6, | |
|
581 | not_empty=False)) | |
|
77 | password = All( | |
|
78 | v.ValidPassword(), | |
|
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) | |
|
584 | name = UnicodeString(strip=True, min=1, not_empty=False) | |
|
585 | lastname = UnicodeString(strip=True, min=1, not_empty=False) | |
|
586 | email = All(Email(not_empty=True), UniqSystemEmail(old_data)) | |
|
86 | active = v.StringBoolean(if_missing=False) | |
|
87 | name = v.UnicodeString(strip=True, min=1, not_empty=False) | |
|
88 | lastname = v.UnicodeString(strip=True, min=1, not_empty=False) | |
|
89 | email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data)) | |
|
587 | 90 | |
|
588 |
chained_validators = [ValidPasswordsMatch |
|
|
91 | chained_validators = [v.ValidPasswordsMatch()] | |
|
589 | 92 | |
|
590 | 93 | return _UserForm |
|
591 | 94 | |
@@ -595,15 +98,18 b' def UsersGroupForm(edit=False, old_data=' | |||
|
595 | 98 | allow_extra_fields = True |
|
596 | 99 | filter_extra_fields = True |
|
597 | 100 | |
|
598 | users_group_name = All(UnicodeString(strip=True, min=1, not_empty=True), | |
|
599 | ValidUsersGroup(edit, old_data)) | |
|
101 | users_group_name = All( | |
|
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 | 108 | if edit: |
|
604 |
users_group_members = OneOf( |
|
|
605 | testValueList=True, | |
|
606 |
|
|
|
109 | users_group_members = v.OneOf( | |
|
110 | available_members, hideList=False, testValueList=True, | |
|
111 | if_missing=None, not_empty=False | |
|
112 | ) | |
|
607 | 113 | |
|
608 | 114 | return _UsersGroupForm |
|
609 | 115 | |
@@ -613,15 +119,16 b' def ReposGroupForm(edit=False, old_data=' | |||
|
613 | 119 | allow_extra_fields = True |
|
614 | 120 | filter_extra_fields = False |
|
615 | 121 | |
|
616 | group_name = All(UnicodeString(strip=True, min=1, not_empty=True), | |
|
617 | SlugifyName()) | |
|
618 | group_description = UnicodeString(strip=True, min=1, | |
|
122 | group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), | |
|
123 | v.SlugifyName()) | |
|
124 | group_description = v.UnicodeString(strip=True, min=1, | |
|
619 | 125 | not_empty=True) |
|
620 | group_parent_id = OneOf(available_groups, hideList=False, | |
|
126 | group_parent_id = v.OneOf(available_groups, hideList=False, | |
|
621 | 127 | testValueList=True, |
|
622 | 128 | if_missing=None, not_empty=False) |
|
623 | 129 | |
|
624 |
chained_validators = [ValidReposGroup(edit, old_data), |
|
|
130 | chained_validators = [v.ValidReposGroup(edit, old_data), | |
|
131 | v.ValidPerms('group')] | |
|
625 | 132 | |
|
626 | 133 | return _ReposGroupForm |
|
627 | 134 | |
@@ -630,16 +137,24 b' def RegisterForm(edit=False, old_data={}' | |||
|
630 | 137 | class _RegisterForm(formencode.Schema): |
|
631 | 138 | allow_extra_fields = True |
|
632 | 139 | filter_extra_fields = True |
|
633 |
username = All( |
|
|
634 | UnicodeString(strip=True, min=1, not_empty=True)) | |
|
635 |
|
|
|
636 | password_confirmation = All(UnicodeString(strip=False, min=6, not_empty=True)) | |
|
637 | active = StringBoolean(if_missing=False) | |
|
638 | name = UnicodeString(strip=True, min=1, not_empty=False) | |
|
639 |
|
|
|
640 | email = All(Email(not_empty=True), UniqSystemEmail(old_data)) | |
|
140 | username = All( | |
|
141 | v.ValidUsername(edit, old_data), | |
|
142 | v.UnicodeString(strip=True, min=1, not_empty=True) | |
|
143 | ) | |
|
144 | password = All( | |
|
145 | v.ValidPassword(), | |
|
146 | v.UnicodeString(strip=False, min=6, not_empty=True) | |
|
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 |
|
|
157 | chained_validators = [v.ValidPasswordsMatch()] | |
|
643 | 158 | |
|
644 | 159 | return _RegisterForm |
|
645 | 160 | |
@@ -648,7 +163,7 b' def PasswordResetForm():' | |||
|
648 | 163 | class _PasswordResetForm(formencode.Schema): |
|
649 | 164 | allow_extra_fields = True |
|
650 | 165 | filter_extra_fields = True |
|
651 | email = All(ValidSystemEmail(), Email(not_empty=True)) | |
|
166 | email = All(v.ValidSystemEmail(), v.Email(not_empty=True)) | |
|
652 | 167 | return _PasswordResetForm |
|
653 | 168 | |
|
654 | 169 | |
@@ -657,24 +172,24 b' def RepoForm(edit=False, old_data={}, su' | |||
|
657 | 172 | class _RepoForm(formencode.Schema): |
|
658 | 173 | allow_extra_fields = True |
|
659 | 174 | filter_extra_fields = False |
|
660 | repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), | |
|
661 | SlugifyName()) | |
|
662 | clone_uri = All(UnicodeString(strip=True, min=1, not_empty=False)) | |
|
663 | repo_group = OneOf(repo_groups, hideList=True) | |
|
664 | repo_type = OneOf(supported_backends) | |
|
665 | description = UnicodeString(strip=True, min=1, not_empty=False) | |
|
666 | private = StringBoolean(if_missing=False) | |
|
667 | enable_statistics = StringBoolean(if_missing=False) | |
|
668 | enable_downloads = StringBoolean(if_missing=False) | |
|
669 | landing_rev = OneOf(landing_revs, hideList=True) | |
|
175 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), | |
|
176 | v.SlugifyName()) | |
|
177 | clone_uri = All(v.UnicodeString(strip=True, min=1, not_empty=False)) | |
|
178 | repo_group = v.OneOf(repo_groups, hideList=True) | |
|
179 | repo_type = v.OneOf(supported_backends) | |
|
180 | description = v.UnicodeString(strip=True, min=1, not_empty=False) | |
|
181 | private = v.StringBoolean(if_missing=False) | |
|
182 | enable_statistics = v.StringBoolean(if_missing=False) | |
|
183 | enable_downloads = v.StringBoolean(if_missing=False) | |
|
184 | landing_rev = v.OneOf(landing_revs, hideList=True) | |
|
670 | 185 | |
|
671 | 186 | if edit: |
|
672 | 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 |
|
|
676 | ValidRepoName(edit, old_data), | |
|
677 | ValidPerms()] | |
|
190 | chained_validators = [v.ValidCloneUri(), | |
|
191 | v.ValidRepoName(edit, old_data), | |
|
192 | v.ValidPerms()] | |
|
678 | 193 | return _RepoForm |
|
679 | 194 | |
|
680 | 195 | |
@@ -683,33 +198,34 b' def RepoForkForm(edit=False, old_data={}' | |||
|
683 | 198 | class _RepoForkForm(formencode.Schema): |
|
684 | 199 | allow_extra_fields = True |
|
685 | 200 | filter_extra_fields = False |
|
686 | repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), | |
|
687 | SlugifyName()) | |
|
688 | repo_group = OneOf(repo_groups, hideList=True) | |
|
689 | repo_type = All(ValidForkType(old_data), OneOf(supported_backends)) | |
|
690 | description = UnicodeString(strip=True, min=1, not_empty=True) | |
|
691 | private = StringBoolean(if_missing=False) | |
|
692 | copy_permissions = StringBoolean(if_missing=False) | |
|
693 | update_after_clone = StringBoolean(if_missing=False) | |
|
694 | fork_parent_id = UnicodeString() | |
|
695 | chained_validators = [ValidForkName(edit, old_data)] | |
|
201 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), | |
|
202 | v.SlugifyName()) | |
|
203 | repo_group = v.OneOf(repo_groups, hideList=True) | |
|
204 | repo_type = All(v.ValidForkType(old_data), v.OneOf(supported_backends)) | |
|
205 | description = v.UnicodeString(strip=True, min=1, not_empty=True) | |
|
206 | private = v.StringBoolean(if_missing=False) | |
|
207 | copy_permissions = v.StringBoolean(if_missing=False) | |
|
208 | update_after_clone = v.StringBoolean(if_missing=False) | |
|
209 | fork_parent_id = v.UnicodeString() | |
|
210 | chained_validators = [v.ValidForkName(edit, old_data)] | |
|
696 | 211 | |
|
697 | 212 | return _RepoForkForm |
|
698 | 213 | |
|
699 | 214 | |
|
700 |
def RepoSettingsForm(edit=False, old_data={}, |
|
|
701 | repo_groups=[], landing_revs=[]): | |
|
215 | def RepoSettingsForm(edit=False, old_data={}, | |
|
216 | supported_backends=BACKENDS.keys(), repo_groups=[], | |
|
217 | landing_revs=[]): | |
|
702 | 218 | class _RepoForm(formencode.Schema): |
|
703 | 219 | allow_extra_fields = True |
|
704 | 220 | filter_extra_fields = False |
|
705 | repo_name = All(UnicodeString(strip=True, min=1, not_empty=True), | |
|
706 | SlugifyName()) | |
|
707 | description = UnicodeString(strip=True, min=1, not_empty=True) | |
|
708 | repo_group = OneOf(repo_groups, hideList=True) | |
|
709 | private = StringBoolean(if_missing=False) | |
|
710 | landing_rev = OneOf(landing_revs, hideList=True) | |
|
711 | chained_validators = [ValidRepoName(edit, old_data), ValidPerms(), | |
|
712 | ValidSettings] | |
|
221 | repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True), | |
|
222 | v.SlugifyName()) | |
|
223 | description = v.UnicodeString(strip=True, min=1, not_empty=True) | |
|
224 | repo_group = v.OneOf(repo_groups, hideList=True) | |
|
225 | private = v.StringBoolean(if_missing=False) | |
|
226 | landing_rev = v.OneOf(landing_revs, hideList=True) | |
|
227 | chained_validators = [v.ValidRepoName(edit, old_data), v.ValidPerms(), | |
|
228 | v.ValidSettings()] | |
|
713 | 229 | return _RepoForm |
|
714 | 230 | |
|
715 | 231 | |
@@ -717,9 +233,9 b' def ApplicationSettingsForm():' | |||
|
717 | 233 | class _ApplicationSettingsForm(formencode.Schema): |
|
718 | 234 | allow_extra_fields = True |
|
719 | 235 | filter_extra_fields = False |
|
720 | rhodecode_title = UnicodeString(strip=True, min=1, not_empty=True) | |
|
721 | rhodecode_realm = UnicodeString(strip=True, min=1, not_empty=True) | |
|
722 | rhodecode_ga_code = UnicodeString(strip=True, min=1, not_empty=False) | |
|
236 | rhodecode_title = v.UnicodeString(strip=True, min=1, not_empty=True) | |
|
237 | rhodecode_realm = v.UnicodeString(strip=True, min=1, not_empty=True) | |
|
238 | rhodecode_ga_code = v.UnicodeString(strip=True, min=1, not_empty=False) | |
|
723 | 239 | |
|
724 | 240 | return _ApplicationSettingsForm |
|
725 | 241 | |
@@ -728,12 +244,19 b' def ApplicationUiSettingsForm():' | |||
|
728 | 244 | class _ApplicationUiSettingsForm(formencode.Schema): |
|
729 | 245 | allow_extra_fields = True |
|
730 | 246 | filter_extra_fields = False |
|
731 | web_push_ssl = OneOf(['true', 'false'], if_missing='false') | |
|
732 | paths_root_path = All(ValidPath(), UnicodeString(strip=True, min=1, not_empty=True)) | |
|
733 | hooks_changegroup_update = OneOf(['True', 'False'], if_missing=False) | |
|
734 | hooks_changegroup_repo_size = OneOf(['True', 'False'], if_missing=False) | |
|
735 | hooks_changegroup_push_logger = OneOf(['True', 'False'], if_missing=False) | |
|
736 |
hooks_ |
|
|
247 | web_push_ssl = v.OneOf(['true', 'false'], if_missing='false') | |
|
248 | paths_root_path = All( | |
|
249 | v.ValidPath(), | |
|
250 | v.UnicodeString(strip=True, min=1, not_empty=True) | |
|
251 | ) | |
|
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 | 261 | return _ApplicationUiSettingsForm |
|
739 | 262 | |
@@ -742,33 +265,37 b' def DefaultPermissionsForm(perms_choices' | |||
|
742 | 265 | class _DefaultPermissionsForm(formencode.Schema): |
|
743 | 266 | allow_extra_fields = True |
|
744 | 267 | filter_extra_fields = True |
|
745 | overwrite_default = StringBoolean(if_missing=False) | |
|
746 | anonymous = OneOf(['True', 'False'], if_missing=False) | |
|
747 | default_perm = OneOf(perms_choices) | |
|
748 | default_register = OneOf(register_choices) | |
|
749 | default_create = OneOf(create_choices) | |
|
268 | overwrite_default = v.StringBoolean(if_missing=False) | |
|
269 | anonymous = v.OneOf(['True', 'False'], if_missing=False) | |
|
270 | default_perm = v.OneOf(perms_choices) | |
|
271 | default_register = v.OneOf(register_choices) | |
|
272 | default_create = v.OneOf(create_choices) | |
|
750 | 273 | |
|
751 | 274 | return _DefaultPermissionsForm |
|
752 | 275 | |
|
753 | 276 | |
|
754 |
def LdapSettingsForm(tls_reqcert_choices, search_scope_choices, |
|
|
277 | def LdapSettingsForm(tls_reqcert_choices, search_scope_choices, | |
|
278 | tls_kind_choices): | |
|
755 | 279 | class _LdapSettingsForm(formencode.Schema): |
|
756 | 280 | allow_extra_fields = True |
|
757 | 281 | filter_extra_fields = True |
|
758 | 282 | #pre_validators = [LdapLibValidator] |
|
759 | ldap_active = StringBoolean(if_missing=False) | |
|
760 | ldap_host = UnicodeString(strip=True,) | |
|
761 | ldap_port = Number(strip=True,) | |
|
762 | ldap_tls_kind = OneOf(tls_kind_choices) | |
|
763 | ldap_tls_reqcert = OneOf(tls_reqcert_choices) | |
|
764 | ldap_dn_user = UnicodeString(strip=True,) | |
|
765 | ldap_dn_pass = UnicodeString(strip=True,) | |
|
766 | ldap_base_dn = UnicodeString(strip=True,) | |
|
767 | ldap_filter = UnicodeString(strip=True,) | |
|
768 | ldap_search_scope = OneOf(search_scope_choices) | |
|
769 | ldap_attr_login = All(AttrLoginValidator, UnicodeString(strip=True,)) | |
|
770 | ldap_attr_firstname = UnicodeString(strip=True,) | |
|
771 |
|
|
|
772 | ldap_attr_email = UnicodeString(strip=True,) | |
|
283 | ldap_active = v.StringBoolean(if_missing=False) | |
|
284 | ldap_host = v.UnicodeString(strip=True,) | |
|
285 | ldap_port = v.Number(strip=True,) | |
|
286 | ldap_tls_kind = v.OneOf(tls_kind_choices) | |
|
287 | ldap_tls_reqcert = v.OneOf(tls_reqcert_choices) | |
|
288 | ldap_dn_user = v.UnicodeString(strip=True,) | |
|
289 | ldap_dn_pass = v.UnicodeString(strip=True,) | |
|
290 | ldap_base_dn = v.UnicodeString(strip=True,) | |
|
291 | ldap_filter = v.UnicodeString(strip=True,) | |
|
292 | ldap_search_scope = v.OneOf(search_scope_choices) | |
|
293 | ldap_attr_login = All( | |
|
294 | v.AttrLoginValidator(), | |
|
295 | v.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 | 301 | return _LdapSettingsForm |
@@ -199,13 +199,13 b' class ReposGroupModel(BaseModel):' | |||
|
199 | 199 | log.error(traceback.format_exc()) |
|
200 | 200 | raise |
|
201 | 201 | |
|
202 |
def delete(self, |
|
|
202 | def delete(self, repos_group): | |
|
203 | repos_group = self.__get_repos_group(repos_group) | |
|
203 | 204 | try: |
|
204 | users_group = RepoGroup.get(users_group_id) | |
|
205 |
self. |
|
|
206 | self.__delete_group(users_group) | |
|
205 | self.sa.delete(repos_group) | |
|
206 | self.__delete_group(repos_group) | |
|
207 | 207 | except: |
|
208 | log.error(traceback.format_exc()) | |
|
208 | log.exception('Error removing repos_group %s' % repos_group) | |
|
209 | 209 | raise |
|
210 | 210 | |
|
211 | 211 | def grant_user_permission(self, repos_group, user, perm): |
@@ -87,9 +87,12 b' class UserModel(BaseModel):' | |||
|
87 | 87 | return User.get_by_api_key(api_key, cache) |
|
88 | 88 | |
|
89 | 89 | def create(self, form_data): |
|
90 | from rhodecode.lib.auth import get_crypt_password | |
|
90 | 91 | try: |
|
91 | 92 | new_user = User() |
|
92 | 93 | for k, v in form_data.items(): |
|
94 | if k == 'password': | |
|
95 | v = get_crypt_password(v) | |
|
93 | 96 | setattr(new_user, k, v) |
|
94 | 97 | |
|
95 | 98 | new_user.api_key = generate_api_key(form_data['username']) |
@@ -265,15 +268,17 b' class UserModel(BaseModel):' | |||
|
265 | 268 | raise |
|
266 | 269 | |
|
267 | 270 | def update_my_account(self, user_id, form_data): |
|
271 | from rhodecode.lib.auth import get_crypt_password | |
|
268 | 272 | try: |
|
269 | 273 | user = self.get(user_id, cache=False) |
|
270 | 274 | if user.username == 'default': |
|
271 | 275 | raise DefaultUserException( |
|
272 |
|
|
|
273 |
|
|
|
276 | _("You can't Edit this user since it's" | |
|
277 | " crucial for entire application") | |
|
278 | ) | |
|
274 | 279 | for k, v in form_data.items(): |
|
275 | 280 | if k == 'new_password' and v != '': |
|
276 | user.password = v | |
|
281 | user.password = get_crypt_password(v) | |
|
277 | 282 | user.api_key = generate_api_key(user.username) |
|
278 | 283 | else: |
|
279 | 284 | if k not in ['admin', 'active']: |
@@ -3,6 +3,8 b'' | |||
|
3 | 3 | from rhodecode.lib.auth import get_crypt_password, check_password |
|
4 | 4 | from rhodecode.model.db import User, RhodeCodeSetting |
|
5 | 5 | from rhodecode.tests import * |
|
6 | from rhodecode.lib import helpers as h | |
|
7 | ||
|
6 | 8 | |
|
7 | 9 | class TestAdminSettingsController(TestController): |
|
8 | 10 | |
@@ -47,7 +49,6 b' class TestAdminSettingsController(TestCo' | |||
|
47 | 49 | response = self.app.get(url('formatted_admin_edit_setting', |
|
48 | 50 | setting_id=1, format='xml')) |
|
49 | 51 | |
|
50 | ||
|
51 | 52 | def test_ga_code_active(self): |
|
52 | 53 | self.log_user() |
|
53 | 54 | old_title = 'RhodeCode' |
@@ -92,7 +93,6 b' class TestAdminSettingsController(TestCo' | |||
|
92 | 93 | self.assertTrue("""_gaq.push(['_setAccount', '%s']);""" % new_ga_code |
|
93 | 94 | not in response.body) |
|
94 | 95 | |
|
95 | ||
|
96 | 96 | def test_title_change(self): |
|
97 | 97 | self.log_user() |
|
98 | 98 | old_title = 'RhodeCode' |
@@ -117,7 +117,6 b' class TestAdminSettingsController(TestCo' | |||
|
117 | 117 | self.assertTrue("""<h1><a href="/">%s</a></h1>""" % new_title |
|
118 | 118 | in response.body) |
|
119 | 119 | |
|
120 | ||
|
121 | 120 | def test_my_account(self): |
|
122 | 121 | self.log_user() |
|
123 | 122 | response = self.app.get(url('admin_settings_my_account')) |
@@ -132,12 +131,11 b' class TestAdminSettingsController(TestCo' | |||
|
132 | 131 | new_lastname = 'NewLastname' |
|
133 | 132 | new_password = 'test123' |
|
134 | 133 | |
|
135 | ||
|
136 | 134 | response = self.app.post(url('admin_settings_my_account_update'), |
|
137 | 135 | params=dict(_method='put', |
|
138 | 136 | username='test_admin', |
|
139 | 137 | new_password=new_password, |
|
140 |
password_confirmation |
|
|
138 | password_confirmation=new_password, | |
|
141 | 139 | password='', |
|
142 | 140 | name=new_name, |
|
143 | 141 | lastname=new_lastname, |
@@ -146,7 +144,7 b' class TestAdminSettingsController(TestCo' | |||
|
146 | 144 | |
|
147 | 145 | assert 'Your account was updated successfully' in response.session['flash'][0][1], 'no flash message about success of change' |
|
148 | 146 | user = self.Session.query(User).filter(User.username == 'test_admin').one() |
|
149 |
assert user.email == new_email |
|
|
147 | assert user.email == new_email, 'incorrect user email after update got %s vs %s' % (user.email, new_email) | |
|
150 | 148 | assert user.name == new_name, 'updated field mismatch %s vs %s' % (user.name, new_name) |
|
151 | 149 | assert user.lastname == new_lastname, 'updated field mismatch %s vs %s' % (user.lastname, new_lastname) |
|
152 | 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 | 159 | _method='put', |
|
162 | 160 | username='test_admin', |
|
163 | 161 | new_password=old_password, |
|
164 |
password_confirmation |
|
|
162 | password_confirmation=old_password, | |
|
165 | 163 | password='', |
|
166 | 164 | name=old_name, |
|
167 | 165 | lastname=old_lastname, |
@@ -172,41 +170,46 b' class TestAdminSettingsController(TestCo' | |||
|
172 | 170 | 'Your account was updated successfully') |
|
173 | 171 | |
|
174 | 172 | user = self.Session.query(User).filter(User.username == 'test_admin').one() |
|
175 |
assert 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 |
|
|
175 | assert user.email == old_email, 'incorrect user email after update got %s vs %s' % (user.email, old_email) | |
|
178 | 176 | assert user.name == old_name, 'updated field mismatch %s vs %s' % (user.name, old_name) |
|
179 | 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 |
|
|
181 | ||
|
178 | assert check_password(old_password, user.password) is True, 'password updated field mismatch %s vs %s' % (user.password, old_password) | |
|
182 | 179 | |
|
183 | 180 | def test_my_account_update_err_email_exists(self): |
|
184 | 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 | 184 | response = self.app.post(url('admin_settings_my_account_update'), params=dict( |
|
188 | 185 | _method='put', |
|
189 | 186 | username='test_admin', |
|
190 | 187 | new_password='test12', |
|
191 |
password_confirmation |
|
|
188 | password_confirmation='test122', | |
|
192 | 189 | name='NewName', |
|
193 | 190 | lastname='NewLastname', |
|
194 | 191 | email=new_email,)) |
|
195 | 192 | |
|
196 | 193 | assert 'This e-mail address is already taken' in response.body, 'Missing error message about existing email' |
|
197 | 194 | |
|
198 | ||
|
199 | 195 | def test_my_account_update_err(self): |
|
200 | 196 | self.log_user('test_regular2', 'test12') |
|
201 | 197 | |
|
202 | 198 | new_email = 'newmail.pl' |
|
203 |
response = self.app.post(url('admin_settings_my_account_update'), |
|
|
204 | _method='put', | |
|
205 |
|
|
|
206 |
|
|
|
207 |
|
|
|
208 |
|
|
|
209 |
|
|
|
210 |
|
|
|
211 | assert 'An email address must contain a single @' in response.body, 'Missing error message about wrong email' | |
|
212 | assert 'This username already exists' in response.body, 'Missing error message about existing user' | |
|
199 | response = self.app.post(url('admin_settings_my_account_update'), | |
|
200 | params=dict( | |
|
201 | _method='put', | |
|
202 | username='test_admin', | |
|
203 | new_password='test12', | |
|
204 | password_confirmation='test122', | |
|
205 | name='NewName', | |
|
206 | lastname='NewLastname', | |
|
207 | email=new_email,) | |
|
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 | 3 | from rhodecode.tests import * |
|
2 | 4 | from rhodecode.model.db import User, Permission |
|
3 | 5 | from rhodecode.lib.auth import check_password |
|
4 | from sqlalchemy.orm.exc import NoResultFound | |
|
5 | 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 | 11 | class TestAdminUsersController(TestController): |
|
8 | 12 | |
@@ -24,26 +28,25 b' class TestAdminUsersController(TestContr' | |||
|
24 | 28 | email = 'mail@mail.com' |
|
25 | 29 | |
|
26 | 30 | response = self.app.post(url('users'), |
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
|
31 | {'username': username, | |
|
32 | 'password': password, | |
|
33 | 'password_confirmation': password_confirmation, | |
|
34 | 'name': name, | |
|
35 | 'active': True, | |
|
36 | 'lastname': lastname, | |
|
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 | 42 | new_user = self.Session.query(User).\ |
|
40 | 43 | filter(User.username == username).one() |
|
41 | 44 | |
|
42 | self.assertEqual(new_user.username,username) | |
|
43 | self.assertEqual(check_password(password, new_user.password),True) | |
|
44 | self.assertEqual(new_user.name,name) | |
|
45 | self.assertEqual(new_user.lastname,lastname) | |
|
46 | self.assertEqual(new_user.email,email) | |
|
45 | self.assertEqual(new_user.username, username) | |
|
46 | self.assertEqual(check_password(password, new_user.password), True) | |
|
47 | self.assertEqual(new_user.name, name) | |
|
48 | self.assertEqual(new_user.lastname, lastname) | |
|
49 | self.assertEqual(new_user.email, email) | |
|
47 | 50 | |
|
48 | 51 | response.follow() |
|
49 | 52 | response = response.follow() |
@@ -57,16 +60,18 b' class TestAdminUsersController(TestContr' | |||
|
57 | 60 | lastname = 'lastname' |
|
58 | 61 | email = 'errmail.com' |
|
59 | 62 | |
|
60 | response = self.app.post(url('users'), {'username':username, | |
|
61 | 'password':password, | |
|
62 | 'name':name, | |
|
63 | 'active':False, | |
|
64 | 'lastname':lastname, | |
|
65 | 'email':email}) | |
|
63 | response = self.app.post(url('users'), {'username': username, | |
|
64 | 'password': password, | |
|
65 | 'name': name, | |
|
66 | 'active': False, | |
|
67 | 'lastname': lastname, | |
|
68 | 'email': email}) | |
|
66 | 69 | |
|
67 | self.assertTrue("""<span class="error-message">Invalid username</span>""" in response.body) | |
|
68 | self.assertTrue("""<span class="error-message">Please enter a value</span>""" in response.body) | |
|
69 | self.assertTrue("""<span class="error-message">An email address must contain a single @</span>""" in response.body) | |
|
70 | msg = validators.ValidUsername(False, {})._messages['system_invalid_username'] | |
|
71 | msg = h.html_escape(msg % {'username': 'new_user'}) | |
|
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 | 76 | def get_user(): |
|
72 | 77 | self.Session.query(User).filter(User.username == username).one() |
@@ -94,13 +99,13 b' class TestAdminUsersController(TestContr' | |||
|
94 | 99 | lastname = 'lastname' |
|
95 | 100 | email = 'todeletemail@mail.com' |
|
96 | 101 | |
|
97 | response = self.app.post(url('users'), {'username':username, | |
|
98 | 'password':password, | |
|
99 | 'password_confirmation':password, | |
|
100 | 'name':name, | |
|
101 | 'active':True, | |
|
102 | 'lastname':lastname, | |
|
103 | 'email':email}) | |
|
102 | response = self.app.post(url('users'), {'username': username, | |
|
103 | 'password': password, | |
|
104 | 'password_confirmation': password, | |
|
105 | 'name': name, | |
|
106 | 'active': True, | |
|
107 | 'lastname': lastname, | |
|
108 | 'email': email}) | |
|
104 | 109 | |
|
105 | 110 | response = response.follow() |
|
106 | 111 | |
@@ -111,7 +116,6 b' class TestAdminUsersController(TestContr' | |||
|
111 | 116 | self.assertTrue("""successfully deleted user""" in |
|
112 | 117 | response.session['flash'][0]) |
|
113 | 118 | |
|
114 | ||
|
115 | 119 | def test_delete_browser_fakeout(self): |
|
116 | 120 | response = self.app.post(url('user', id=1), |
|
117 | 121 | params=dict(_method='delete')) |
@@ -127,7 +131,6 b' class TestAdminUsersController(TestContr' | |||
|
127 | 131 | user = User.get_by_username(TEST_USER_ADMIN_LOGIN) |
|
128 | 132 | response = self.app.get(url('edit_user', id=user.user_id)) |
|
129 | 133 | |
|
130 | ||
|
131 | 134 | def test_add_perm_create_repo(self): |
|
132 | 135 | self.log_user() |
|
133 | 136 | perm_none = Permission.get_by_key('hg.create.none') |
@@ -135,7 +138,6 b' class TestAdminUsersController(TestContr' | |||
|
135 | 138 | |
|
136 | 139 | user = User.get_by_username(TEST_USER_REGULAR_LOGIN) |
|
137 | 140 | |
|
138 | ||
|
139 | 141 | #User should have None permission on creation repository |
|
140 | 142 | self.assertEqual(UserModel().has_perm(user, perm_none), False) |
|
141 | 143 | self.assertEqual(UserModel().has_perm(user, perm_create), False) |
@@ -159,7 +161,6 b' class TestAdminUsersController(TestContr' | |||
|
159 | 161 | |
|
160 | 162 | user = User.get_by_username(TEST_USER_REGULAR2_LOGIN) |
|
161 | 163 | |
|
162 | ||
|
163 | 164 | #User should have None permission on creation repository |
|
164 | 165 | self.assertEqual(UserModel().has_perm(user, perm_none), False) |
|
165 | 166 | self.assertEqual(UserModel().has_perm(user, perm_create), False) |
@@ -4,6 +4,8 b' from rhodecode.model.db import User, Not' | |||
|
4 | 4 | from rhodecode.lib.utils2 import generate_api_key |
|
5 | 5 | from rhodecode.lib.auth import check_password |
|
6 | 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 | 11 | class TestLoginController(TestController): |
@@ -22,21 +24,21 b' class TestLoginController(TestController' | |||
|
22 | 24 | |
|
23 | 25 | def test_login_admin_ok(self): |
|
24 | 26 | response = self.app.post(url(controller='login', action='index'), |
|
25 | {'username':'test_admin', | |
|
26 | 'password':'test12'}) | |
|
27 | {'username': 'test_admin', | |
|
28 | 'password': 'test12'}) | |
|
27 | 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 | 31 | 'test_admin') |
|
30 | 32 | response = response.follow() |
|
31 | 33 | self.assertTrue('%s repository' % HG_REPO in response.body) |
|
32 | 34 | |
|
33 | 35 | def test_login_regular_ok(self): |
|
34 | 36 | response = self.app.post(url(controller='login', action='index'), |
|
35 | {'username':'test_regular', | |
|
36 | 'password':'test12'}) | |
|
37 | {'username': 'test_regular', | |
|
38 | 'password': 'test12'}) | |
|
37 | 39 | |
|
38 | 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 | 42 | 'test_regular') |
|
41 | 43 | response = response.follow() |
|
42 | 44 | self.assertTrue('%s repository' % HG_REPO in response.body) |
@@ -46,8 +48,8 b' class TestLoginController(TestController' | |||
|
46 | 48 | test_came_from = '/_admin/users' |
|
47 | 49 | response = self.app.post(url(controller='login', action='index', |
|
48 | 50 | came_from=test_came_from), |
|
49 | {'username':'test_admin', | |
|
50 | 'password':'test12'}) | |
|
51 | {'username': 'test_admin', | |
|
52 | 'password': 'test12'}) | |
|
51 | 53 | self.assertEqual(response.status, '302 Found') |
|
52 | 54 | response = response.follow() |
|
53 | 55 | |
@@ -56,17 +58,16 b' class TestLoginController(TestController' | |||
|
56 | 58 | |
|
57 | 59 | def test_login_short_password(self): |
|
58 | 60 | response = self.app.post(url(controller='login', action='index'), |
|
59 | {'username':'test_admin', | |
|
60 | 'password':'as'}) | |
|
61 | {'username': 'test_admin', | |
|
62 | 'password': 'as'}) | |
|
61 | 63 | self.assertEqual(response.status, '200 OK') |
|
62 | 64 | |
|
63 | 65 | self.assertTrue('Enter 3 characters or more' in response.body) |
|
64 | 66 | |
|
65 | 67 | def test_login_wrong_username_password(self): |
|
66 | 68 | response = self.app.post(url(controller='login', action='index'), |
|
67 | {'username':'error', | |
|
68 | 'password':'test12'}) | |
|
69 | self.assertEqual(response.status , '200 OK') | |
|
69 | {'username': 'error', | |
|
70 | 'password': 'test12'}) | |
|
70 | 71 | |
|
71 | 72 | self.assertTrue('invalid user name' in response.body) |
|
72 | 73 | self.assertTrue('invalid password' in response.body) |
@@ -79,62 +80,63 b' class TestLoginController(TestController' | |||
|
79 | 80 | self.assertTrue('Sign Up to RhodeCode' in response.body) |
|
80 | 81 | |
|
81 | 82 | def test_register_err_same_username(self): |
|
83 | uname = 'test_admin' | |
|
82 | 84 | response = self.app.post(url(controller='login', action='register'), |
|
83 |
{'username': |
|
|
84 | 'password':'test12', | |
|
85 | 'password_confirmation':'test12', | |
|
86 | 'email':'goodmail@domain.com', | |
|
87 | 'name':'test', | |
|
88 | 'lastname':'test'}) | |
|
85 | {'username': uname, | |
|
86 | 'password': 'test12', | |
|
87 | 'password_confirmation': 'test12', | |
|
88 | 'email': 'goodmail@domain.com', | |
|
89 | 'name': 'test', | |
|
90 | 'lastname': 'test'}) | |
|
89 | 91 | |
|
90 | self.assertEqual(response.status , '200 OK') | |
|
91 | self.assertTrue('This username already exists' in response.body) | |
|
92 | msg = validators.ValidUsername()._messages['username_exists'] | |
|
93 | msg = h.html_escape(msg % {'username': uname}) | |
|
94 | response.mustcontain(msg) | |
|
92 | 95 | |
|
93 | 96 | def test_register_err_same_email(self): |
|
94 | 97 | response = self.app.post(url(controller='login', action='register'), |
|
95 | {'username':'test_admin_0', | |
|
96 | 'password':'test12', | |
|
97 | 'password_confirmation':'test12', | |
|
98 | 'email':'test_admin@mail.com', | |
|
99 | 'name':'test', | |
|
100 | 'lastname':'test'}) | |
|
98 | {'username': 'test_admin_0', | |
|
99 | 'password': 'test12', | |
|
100 | 'password_confirmation': 'test12', | |
|
101 | 'email': 'test_admin@mail.com', | |
|
102 | 'name': 'test', | |
|
103 | 'lastname': 'test'}) | |
|
101 | 104 | |
|
102 | self.assertEqual(response.status , '200 OK') | |
|
103 |
response.mustcontain( |
|
|
105 | msg = validators.UniqSystemEmail()()._messages['email_taken'] | |
|
106 | response.mustcontain(msg) | |
|
104 | 107 | |
|
105 | 108 | def test_register_err_same_email_case_sensitive(self): |
|
106 | 109 | response = self.app.post(url(controller='login', action='register'), |
|
107 | {'username':'test_admin_1', | |
|
108 | 'password':'test12', | |
|
109 | 'password_confirmation':'test12', | |
|
110 | 'email':'TesT_Admin@mail.COM', | |
|
111 | 'name':'test', | |
|
112 | 'lastname':'test'}) | |
|
113 | self.assertEqual(response.status , '200 OK') | |
|
114 |
response.mustcontain( |
|
|
110 | {'username': 'test_admin_1', | |
|
111 | 'password': 'test12', | |
|
112 | 'password_confirmation': 'test12', | |
|
113 | 'email': 'TesT_Admin@mail.COM', | |
|
114 | 'name': 'test', | |
|
115 | 'lastname': 'test'}) | |
|
116 | msg = validators.UniqSystemEmail()()._messages['email_taken'] | |
|
117 | response.mustcontain(msg) | |
|
115 | 118 | |
|
116 | 119 | def test_register_err_wrong_data(self): |
|
117 | 120 | response = self.app.post(url(controller='login', action='register'), |
|
118 | {'username':'xs', | |
|
119 | 'password':'test', | |
|
120 | 'password_confirmation':'test', | |
|
121 | 'email':'goodmailm', | |
|
122 | 'name':'test', | |
|
123 | 'lastname':'test'}) | |
|
124 |
self.assertEqual(response.status |
|
|
121 | {'username': 'xs', | |
|
122 | 'password': 'test', | |
|
123 | 'password_confirmation': 'test', | |
|
124 | 'email': 'goodmailm', | |
|
125 | 'name': 'test', | |
|
126 | 'lastname': 'test'}) | |
|
127 | self.assertEqual(response.status, '200 OK') | |
|
125 | 128 | response.mustcontain('An email address must contain a single @') |
|
126 | 129 | response.mustcontain('Enter a value 6 characters long or more') |
|
127 | 130 | |
|
128 | 131 | def test_register_err_username(self): |
|
129 | 132 | response = self.app.post(url(controller='login', action='register'), |
|
130 | {'username':'error user', | |
|
131 | 'password':'test12', | |
|
132 | 'password_confirmation':'test12', | |
|
133 | 'email':'goodmailm', | |
|
134 | 'name':'test', | |
|
135 | 'lastname':'test'}) | |
|
133 | {'username': 'error user', | |
|
134 | 'password': 'test12', | |
|
135 | 'password_confirmation': 'test12', | |
|
136 | 'email': 'goodmailm', | |
|
137 | 'name': 'test', | |
|
138 | 'lastname': 'test'}) | |
|
136 | 139 | |
|
137 | self.assertEqual(response.status , '200 OK') | |
|
138 | 140 | response.mustcontain('An email address must contain a single @') |
|
139 | 141 | response.mustcontain('Username may only contain ' |
|
140 | 142 | 'alphanumeric characters underscores, ' |
@@ -142,41 +144,42 b' class TestLoginController(TestController' | |||
|
142 | 144 | 'alphanumeric character') |
|
143 | 145 | |
|
144 | 146 | def test_register_err_case_sensitive(self): |
|
147 | usr = 'Test_Admin' | |
|
145 | 148 | response = self.app.post(url(controller='login', action='register'), |
|
146 |
{'username': |
|
|
147 | 'password':'test12', | |
|
148 | 'password_confirmation':'test12', | |
|
149 | 'email':'goodmailm', | |
|
150 | 'name':'test', | |
|
151 | 'lastname':'test'}) | |
|
149 | {'username': usr, | |
|
150 | 'password': 'test12', | |
|
151 | 'password_confirmation': 'test12', | |
|
152 | 'email': 'goodmailm', | |
|
153 | 'name': 'test', | |
|
154 | 'lastname': 'test'}) | |
|
152 | 155 | |
|
153 | self.assertEqual(response.status , '200 OK') | |
|
154 | self.assertTrue('An email address must contain a single @' in response.body) | |
|
155 | self.assertTrue('This username already exists' in response.body) | |
|
156 | response.mustcontain('An email address must contain a single @') | |
|
157 | msg = validators.ValidUsername()._messages['username_exists'] | |
|
158 | msg = h.html_escape(msg % {'username': usr}) | |
|
159 | response.mustcontain(msg) | |
|
156 | 160 | |
|
157 | 161 | def test_register_special_chars(self): |
|
158 | 162 | response = self.app.post(url(controller='login', action='register'), |
|
159 |
|
|
|
160 |
|
|
|
161 |
|
|
|
162 |
|
|
|
163 |
|
|
|
164 |
|
|
|
163 | {'username': 'xxxaxn', | |
|
164 | 'password': 'Δ ΔΕΊΕΌΔ ΕΕΕΕ', | |
|
165 | 'password_confirmation': 'Δ ΔΕΊΕΌΔ ΕΕΕΕ', | |
|
166 | 'email': 'goodmailm@test.plx', | |
|
167 | 'name': 'test', | |
|
168 | 'lastname': 'test'}) | |
|
165 | 169 | |
|
166 | self.assertEqual(response.status , '200 OK') | |
|
167 | self.assertTrue('Invalid characters in password' in response.body) | |
|
170 | msg = validators.ValidPassword()._messages['invalid_password'] | |
|
171 | response.mustcontain(msg) | |
|
168 | 172 | |
|
169 | 173 | def test_register_password_mismatch(self): |
|
170 | 174 | response = self.app.post(url(controller='login', action='register'), |
|
171 | {'username':'xs', | |
|
172 | 'password':'123qwe', | |
|
173 | 'password_confirmation':'qwe123', | |
|
174 | 'email':'goodmailm@test.plxa', | |
|
175 | 'name':'test', | |
|
176 | 'lastname':'test'}) | |
|
177 | ||
|
178 | self.assertEqual(response.status, '200 OK') | |
|
179 | response.mustcontain('Passwords do not match') | |
|
175 | {'username': 'xs', | |
|
176 | 'password': '123qwe', | |
|
177 | 'password_confirmation': 'qwe123', | |
|
178 | 'email': 'goodmailm@test.plxa', | |
|
179 | 'name': 'test', | |
|
180 | 'lastname': 'test'}) | |
|
181 | msg = validators.ValidPasswordsMatch()._messages['password_mismatch'] | |
|
182 | response.mustcontain(msg) | |
|
180 | 183 | |
|
181 | 184 | def test_register_ok(self): |
|
182 | 185 | username = 'test_regular4' |
@@ -186,13 +189,13 b' class TestLoginController(TestController' | |||
|
186 | 189 | lastname = 'testlastname' |
|
187 | 190 | |
|
188 | 191 | response = self.app.post(url(controller='login', action='register'), |
|
189 | {'username':username, | |
|
190 | 'password':password, | |
|
191 | 'password_confirmation':password, | |
|
192 | 'email':email, | |
|
193 | 'name':name, | |
|
194 | 'lastname':lastname, | |
|
195 | 'admin':True}) # This should be overriden | |
|
192 | {'username': username, | |
|
193 | 'password': password, | |
|
194 | 'password_confirmation': password, | |
|
195 | 'email': email, | |
|
196 | 'name': name, | |
|
197 | 'lastname': lastname, | |
|
198 | 'admin': True}) # This should be overriden | |
|
196 | 199 | self.assertEqual(response.status, '302 Found') |
|
197 | 200 | self.checkSessionFlash(response, 'You have successfully registered into rhodecode') |
|
198 | 201 | |
@@ -206,12 +209,15 b' class TestLoginController(TestController' | |||
|
206 | 209 | self.assertEqual(ret.admin, False) |
|
207 | 210 | |
|
208 | 211 | def test_forgot_password_wrong_mail(self): |
|
212 | bad_email = 'marcin@wrongmail.org' | |
|
209 | 213 | response = self.app.post( |
|
210 | 214 | url(controller='login', action='password_reset'), |
|
211 |
{'email': |
|
|
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 | 222 | def test_forgot_password(self): |
|
217 | 223 | response = self.app.get(url(controller='login', |
@@ -236,7 +242,7 b' class TestLoginController(TestController' | |||
|
236 | 242 | |
|
237 | 243 | response = self.app.post(url(controller='login', |
|
238 | 244 | action='password_reset'), |
|
239 | {'email':email, }) | |
|
245 | {'email': email, }) | |
|
240 | 246 | |
|
241 | 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