##// END OF EJS Templates
admin: Use error message from UserCreationError when updating a user....
johbo -
r231:b3a11d63 default
parent child Browse files
Show More
@@ -1,717 +1,719 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 """
22 22 Users crud controller for pylons
23 23 """
24 24
25 25 import logging
26 26 import formencode
27 27
28 28 from formencode import htmlfill
29 29 from pylons import request, tmpl_context as c, url, config
30 30 from pylons.controllers.util import redirect
31 31 from pylons.i18n.translation import _
32 32
33 33 from rhodecode.authentication.plugins import auth_rhodecode
34 34 from rhodecode.lib.exceptions import (
35 35 DefaultUserException, UserOwnsReposException, UserOwnsRepoGroupsException,
36 36 UserOwnsUserGroupsException, UserCreationError)
37 37 from rhodecode.lib import helpers as h
38 38 from rhodecode.lib import auth
39 39 from rhodecode.lib.auth import (
40 40 LoginRequired, HasPermissionAllDecorator, AuthUser, generate_auth_token)
41 41 from rhodecode.lib.base import BaseController, render
42 42 from rhodecode.model.auth_token import AuthTokenModel
43 43
44 44 from rhodecode.model.db import (
45 45 PullRequestReviewers, User, UserEmailMap, UserIpMap, RepoGroup)
46 46 from rhodecode.model.forms import (
47 47 UserForm, UserPermissionsForm, UserIndividualPermissionsForm)
48 48 from rhodecode.model.user import UserModel
49 49 from rhodecode.model.meta import Session
50 50 from rhodecode.model.permission import PermissionModel
51 51 from rhodecode.lib.utils import action_logger
52 52 from rhodecode.lib.ext_json import json
53 53 from rhodecode.lib.utils2 import datetime_to_time, safe_int
54 54
55 55 log = logging.getLogger(__name__)
56 56
57 57
58 58 class UsersController(BaseController):
59 59 """REST Controller styled on the Atom Publishing Protocol"""
60 60
61 61 @LoginRequired()
62 62 def __before__(self):
63 63 super(UsersController, self).__before__()
64 64 c.available_permissions = config['available_permissions']
65 65 c.allowed_languages = [
66 66 ('en', 'English (en)'),
67 67 ('de', 'German (de)'),
68 68 ('fr', 'French (fr)'),
69 69 ('it', 'Italian (it)'),
70 70 ('ja', 'Japanese (ja)'),
71 71 ('pl', 'Polish (pl)'),
72 72 ('pt', 'Portuguese (pt)'),
73 73 ('ru', 'Russian (ru)'),
74 74 ('zh', 'Chinese (zh)'),
75 75 ]
76 76 PermissionModel().set_global_permission_choices(c, translator=_)
77 77
78 78 @HasPermissionAllDecorator('hg.admin')
79 79 def index(self):
80 80 """GET /users: All items in the collection"""
81 81 # url('users')
82 82
83 83 from rhodecode.lib.utils import PartialRenderer
84 84 _render = PartialRenderer('data_table/_dt_elements.html')
85 85
86 86 def grav_tmpl(user_email, size):
87 87 return _render("user_gravatar", user_email, size)
88 88
89 89 def username(user_id, username):
90 90 return _render("user_name", user_id, username)
91 91
92 92 def user_actions(user_id, username):
93 93 return _render("user_actions", user_id, username)
94 94
95 95 # json generate
96 96 c.users_list = User.query()\
97 97 .filter(User.username != User.DEFAULT_USER) \
98 98 .all()
99 99
100 100 users_data = []
101 101 for user in c.users_list:
102 102 users_data.append({
103 103 "gravatar": grav_tmpl(user.email, 20),
104 104 "username": h.link_to(
105 105 user.username, h.url('user_profile', username=user.username)),
106 106 "username_raw": user.username,
107 107 "email": user.email,
108 108 "first_name": h.escape(user.name),
109 109 "last_name": h.escape(user.lastname),
110 110 "last_login": h.format_date(user.last_login),
111 111 "last_login_raw": datetime_to_time(user.last_login),
112 112 "last_activity": h.format_date(
113 113 h.time_to_datetime(user.user_data.get('last_activity', 0))),
114 114 "last_activity_raw": user.user_data.get('last_activity', 0),
115 115 "active": h.bool2icon(user.active),
116 116 "active_raw": user.active,
117 117 "admin": h.bool2icon(user.admin),
118 118 "admin_raw": user.admin,
119 119 "extern_type": user.extern_type,
120 120 "extern_name": user.extern_name,
121 121 "action": user_actions(user.user_id, user.username),
122 122 })
123 123
124 124
125 125 c.data = json.dumps(users_data)
126 126 return render('admin/users/users.html')
127 127
128 128 @HasPermissionAllDecorator('hg.admin')
129 129 @auth.CSRFRequired()
130 130 def create(self):
131 131 """POST /users: Create a new item"""
132 132 # url('users')
133 133 c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name
134 134 user_model = UserModel()
135 135 user_form = UserForm()()
136 136 try:
137 137 form_result = user_form.to_python(dict(request.POST))
138 138 user = user_model.create(form_result)
139 139 Session().flush()
140 140 username = form_result['username']
141 141 action_logger(c.rhodecode_user, 'admin_created_user:%s' % username,
142 142 None, self.ip_addr, self.sa)
143 143
144 144 user_link = h.link_to(h.escape(username),
145 145 url('edit_user',
146 146 user_id=user.user_id))
147 147 h.flash(h.literal(_('Created user %(user_link)s')
148 148 % {'user_link': user_link}), category='success')
149 149 Session().commit()
150 150 except formencode.Invalid as errors:
151 151 return htmlfill.render(
152 152 render('admin/users/user_add.html'),
153 153 defaults=errors.value,
154 154 errors=errors.error_dict or {},
155 155 prefix_error=False,
156 156 encoding="UTF-8",
157 157 force_defaults=False)
158 158 except UserCreationError as e:
159 159 h.flash(e, 'error')
160 160 except Exception:
161 161 log.exception("Exception creation of user")
162 162 h.flash(_('Error occurred during creation of user %s')
163 163 % request.POST.get('username'), category='error')
164 164 return redirect(url('users'))
165 165
166 166 @HasPermissionAllDecorator('hg.admin')
167 167 def new(self):
168 168 """GET /users/new: Form to create a new item"""
169 169 # url('new_user')
170 170 c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name
171 171 return render('admin/users/user_add.html')
172 172
173 173 @HasPermissionAllDecorator('hg.admin')
174 174 @auth.CSRFRequired()
175 175 def update(self, user_id):
176 176 """PUT /users/user_id: Update an existing item"""
177 177 # Forms posted to this method should contain a hidden field:
178 178 # <input type="hidden" name="_method" value="PUT" />
179 179 # Or using helpers:
180 180 # h.form(url('update_user', user_id=ID),
181 181 # method='put')
182 182 # url('user', user_id=ID)
183 183 user_id = safe_int(user_id)
184 184 c.user = User.get_or_404(user_id)
185 185 c.active = 'profile'
186 186 c.extern_type = c.user.extern_type
187 187 c.extern_name = c.user.extern_name
188 188 c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr)
189 189 available_languages = [x[0] for x in c.allowed_languages]
190 190 _form = UserForm(edit=True, available_languages=available_languages,
191 191 old_data={'user_id': user_id,
192 192 'email': c.user.email})()
193 193 form_result = {}
194 194 try:
195 195 form_result = _form.to_python(dict(request.POST))
196 196 skip_attrs = ['extern_type', 'extern_name']
197 197 # TODO: plugin should define if username can be updated
198 198 if c.extern_type != "rhodecode":
199 199 # forbid updating username for external accounts
200 200 skip_attrs.append('username')
201 201
202 202 UserModel().update_user(user_id, skip_attrs=skip_attrs, **form_result)
203 203 usr = form_result['username']
204 204 action_logger(c.rhodecode_user, 'admin_updated_user:%s' % usr,
205 205 None, self.ip_addr, self.sa)
206 206 h.flash(_('User updated successfully'), category='success')
207 207 Session().commit()
208 208 except formencode.Invalid as errors:
209 209 defaults = errors.value
210 210 e = errors.error_dict or {}
211 211
212 212 return htmlfill.render(
213 213 render('admin/users/user_edit.html'),
214 214 defaults=defaults,
215 215 errors=e,
216 216 prefix_error=False,
217 217 encoding="UTF-8",
218 218 force_defaults=False)
219 except UserCreationError as e:
220 h.flash(e, 'error')
219 221 except Exception:
220 222 log.exception("Exception updating user")
221 223 h.flash(_('Error occurred during update of user %s')
222 224 % form_result.get('username'), category='error')
223 225 return redirect(url('edit_user', user_id=user_id))
224 226
225 227 @HasPermissionAllDecorator('hg.admin')
226 228 @auth.CSRFRequired()
227 229 def delete(self, user_id):
228 230 """DELETE /users/user_id: Delete an existing item"""
229 231 # Forms posted to this method should contain a hidden field:
230 232 # <input type="hidden" name="_method" value="DELETE" />
231 233 # Or using helpers:
232 234 # h.form(url('delete_user', user_id=ID),
233 235 # method='delete')
234 236 # url('user', user_id=ID)
235 237 user_id = safe_int(user_id)
236 238 c.user = User.get_or_404(user_id)
237 239
238 240 _repos = c.user.repositories
239 241 _repo_groups = c.user.repository_groups
240 242 _user_groups = c.user.user_groups
241 243
242 244 handle_repos = None
243 245 handle_repo_groups = None
244 246 handle_user_groups = None
245 247 # dummy call for flash of handle
246 248 set_handle_flash_repos = lambda: None
247 249 set_handle_flash_repo_groups = lambda: None
248 250 set_handle_flash_user_groups = lambda: None
249 251
250 252 if _repos and request.POST.get('user_repos'):
251 253 do = request.POST['user_repos']
252 254 if do == 'detach':
253 255 handle_repos = 'detach'
254 256 set_handle_flash_repos = lambda: h.flash(
255 257 _('Detached %s repositories') % len(_repos),
256 258 category='success')
257 259 elif do == 'delete':
258 260 handle_repos = 'delete'
259 261 set_handle_flash_repos = lambda: h.flash(
260 262 _('Deleted %s repositories') % len(_repos),
261 263 category='success')
262 264
263 265 if _repo_groups and request.POST.get('user_repo_groups'):
264 266 do = request.POST['user_repo_groups']
265 267 if do == 'detach':
266 268 handle_repo_groups = 'detach'
267 269 set_handle_flash_repo_groups = lambda: h.flash(
268 270 _('Detached %s repository groups') % len(_repo_groups),
269 271 category='success')
270 272 elif do == 'delete':
271 273 handle_repo_groups = 'delete'
272 274 set_handle_flash_repo_groups = lambda: h.flash(
273 275 _('Deleted %s repository groups') % len(_repo_groups),
274 276 category='success')
275 277
276 278 if _user_groups and request.POST.get('user_user_groups'):
277 279 do = request.POST['user_user_groups']
278 280 if do == 'detach':
279 281 handle_user_groups = 'detach'
280 282 set_handle_flash_user_groups = lambda: h.flash(
281 283 _('Detached %s user groups') % len(_user_groups),
282 284 category='success')
283 285 elif do == 'delete':
284 286 handle_user_groups = 'delete'
285 287 set_handle_flash_user_groups = lambda: h.flash(
286 288 _('Deleted %s user groups') % len(_user_groups),
287 289 category='success')
288 290
289 291 try:
290 292 UserModel().delete(c.user, handle_repos=handle_repos,
291 293 handle_repo_groups=handle_repo_groups,
292 294 handle_user_groups=handle_user_groups)
293 295 Session().commit()
294 296 set_handle_flash_repos()
295 297 set_handle_flash_repo_groups()
296 298 set_handle_flash_user_groups()
297 299 h.flash(_('Successfully deleted user'), category='success')
298 300 except (UserOwnsReposException, UserOwnsRepoGroupsException,
299 301 UserOwnsUserGroupsException, DefaultUserException) as e:
300 302 h.flash(e, category='warning')
301 303 except Exception:
302 304 log.exception("Exception during deletion of user")
303 305 h.flash(_('An error occurred during deletion of user'),
304 306 category='error')
305 307 return redirect(url('users'))
306 308
307 309 @HasPermissionAllDecorator('hg.admin')
308 310 @auth.CSRFRequired()
309 311 def reset_password(self, user_id):
310 312 """
311 313 toggle reset password flag for this user
312 314
313 315 :param user_id:
314 316 """
315 317 user_id = safe_int(user_id)
316 318 c.user = User.get_or_404(user_id)
317 319 try:
318 320 old_value = c.user.user_data.get('force_password_change')
319 321 c.user.update_userdata(force_password_change=not old_value)
320 322 Session().commit()
321 323 if old_value:
322 324 msg = _('Force password change disabled for user')
323 325 else:
324 326 msg = _('Force password change enabled for user')
325 327 h.flash(msg, category='success')
326 328 except Exception:
327 329 log.exception("Exception during password reset for user")
328 330 h.flash(_('An error occurred during password reset for user'),
329 331 category='error')
330 332
331 333 return redirect(url('edit_user_advanced', user_id=user_id))
332 334
333 335 @HasPermissionAllDecorator('hg.admin')
334 336 @auth.CSRFRequired()
335 337 def create_personal_repo_group(self, user_id):
336 338 """
337 339 Create personal repository group for this user
338 340
339 341 :param user_id:
340 342 """
341 343 from rhodecode.model.repo_group import RepoGroupModel
342 344
343 345 user_id = safe_int(user_id)
344 346 c.user = User.get_or_404(user_id)
345 347
346 348 try:
347 349 desc = RepoGroupModel.PERSONAL_GROUP_DESC % {
348 350 'username': c.user.username}
349 351 if not RepoGroup.get_by_group_name(c.user.username):
350 352 RepoGroupModel().create(group_name=c.user.username,
351 353 group_description=desc,
352 354 owner=c.user.username)
353 355
354 356 msg = _('Created repository group `%s`' % (c.user.username,))
355 357 h.flash(msg, category='success')
356 358 except Exception:
357 359 log.exception("Exception during repository group creation")
358 360 msg = _(
359 361 'An error occurred during repository group creation for user')
360 362 h.flash(msg, category='error')
361 363
362 364 return redirect(url('edit_user_advanced', user_id=user_id))
363 365
364 366 @HasPermissionAllDecorator('hg.admin')
365 367 def show(self, user_id):
366 368 """GET /users/user_id: Show a specific item"""
367 369 # url('user', user_id=ID)
368 370 User.get_or_404(-1)
369 371
370 372 @HasPermissionAllDecorator('hg.admin')
371 373 def edit(self, user_id):
372 374 """GET /users/user_id/edit: Form to edit an existing item"""
373 375 # url('edit_user', user_id=ID)
374 376 user_id = safe_int(user_id)
375 377 c.user = User.get_or_404(user_id)
376 378 if c.user.username == User.DEFAULT_USER:
377 379 h.flash(_("You can't edit this user"), category='warning')
378 380 return redirect(url('users'))
379 381
380 382 c.active = 'profile'
381 383 c.extern_type = c.user.extern_type
382 384 c.extern_name = c.user.extern_name
383 385 c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr)
384 386
385 387 defaults = c.user.get_dict()
386 388 defaults.update({'language': c.user.user_data.get('language')})
387 389 return htmlfill.render(
388 390 render('admin/users/user_edit.html'),
389 391 defaults=defaults,
390 392 encoding="UTF-8",
391 393 force_defaults=False)
392 394
393 395 @HasPermissionAllDecorator('hg.admin')
394 396 def edit_advanced(self, user_id):
395 397 user_id = safe_int(user_id)
396 398 user = c.user = User.get_or_404(user_id)
397 399 if user.username == User.DEFAULT_USER:
398 400 h.flash(_("You can't edit this user"), category='warning')
399 401 return redirect(url('users'))
400 402
401 403 c.active = 'advanced'
402 404 c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr)
403 405 c.personal_repo_group = RepoGroup.get_by_group_name(user.username)
404 406 c.first_admin = User.get_first_admin()
405 407 defaults = user.get_dict()
406 408
407 409 # Interim workaround if the user participated on any pull requests as a
408 410 # reviewer.
409 411 has_review = bool(PullRequestReviewers.query().filter(
410 412 PullRequestReviewers.user_id == user_id).first())
411 413 c.can_delete_user = not has_review
412 414 c.can_delete_user_message = _(
413 415 'The user participates as reviewer in pull requests and '
414 416 'cannot be deleted. You can set the user to '
415 417 '"inactive" instead of deleting it.') if has_review else ''
416 418
417 419 return htmlfill.render(
418 420 render('admin/users/user_edit.html'),
419 421 defaults=defaults,
420 422 encoding="UTF-8",
421 423 force_defaults=False)
422 424
423 425 @HasPermissionAllDecorator('hg.admin')
424 426 def edit_auth_tokens(self, user_id):
425 427 user_id = safe_int(user_id)
426 428 c.user = User.get_or_404(user_id)
427 429 if c.user.username == User.DEFAULT_USER:
428 430 h.flash(_("You can't edit this user"), category='warning')
429 431 return redirect(url('users'))
430 432
431 433 c.active = 'auth_tokens'
432 434 show_expired = True
433 435 c.lifetime_values = [
434 436 (str(-1), _('forever')),
435 437 (str(5), _('5 minutes')),
436 438 (str(60), _('1 hour')),
437 439 (str(60 * 24), _('1 day')),
438 440 (str(60 * 24 * 30), _('1 month')),
439 441 ]
440 442 c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
441 443 c.role_values = [(x, AuthTokenModel.cls._get_role_name(x))
442 444 for x in AuthTokenModel.cls.ROLES]
443 445 c.role_options = [(c.role_values, _("Role"))]
444 446 c.user_auth_tokens = AuthTokenModel().get_auth_tokens(
445 447 c.user.user_id, show_expired=show_expired)
446 448 defaults = c.user.get_dict()
447 449 return htmlfill.render(
448 450 render('admin/users/user_edit.html'),
449 451 defaults=defaults,
450 452 encoding="UTF-8",
451 453 force_defaults=False)
452 454
453 455 @HasPermissionAllDecorator('hg.admin')
454 456 @auth.CSRFRequired()
455 457 def add_auth_token(self, user_id):
456 458 user_id = safe_int(user_id)
457 459 c.user = User.get_or_404(user_id)
458 460 if c.user.username == User.DEFAULT_USER:
459 461 h.flash(_("You can't edit this user"), category='warning')
460 462 return redirect(url('users'))
461 463
462 464 lifetime = safe_int(request.POST.get('lifetime'), -1)
463 465 description = request.POST.get('description')
464 466 role = request.POST.get('role')
465 467 AuthTokenModel().create(c.user.user_id, description, lifetime, role)
466 468 Session().commit()
467 469 h.flash(_("Auth token successfully created"), category='success')
468 470 return redirect(url('edit_user_auth_tokens', user_id=c.user.user_id))
469 471
470 472 @HasPermissionAllDecorator('hg.admin')
471 473 @auth.CSRFRequired()
472 474 def delete_auth_token(self, user_id):
473 475 user_id = safe_int(user_id)
474 476 c.user = User.get_or_404(user_id)
475 477 if c.user.username == User.DEFAULT_USER:
476 478 h.flash(_("You can't edit this user"), category='warning')
477 479 return redirect(url('users'))
478 480
479 481 auth_token = request.POST.get('del_auth_token')
480 482 if request.POST.get('del_auth_token_builtin'):
481 483 user = User.get(c.user.user_id)
482 484 if user:
483 485 user.api_key = generate_auth_token(user.username)
484 486 Session().add(user)
485 487 Session().commit()
486 488 h.flash(_("Auth token successfully reset"), category='success')
487 489 elif auth_token:
488 490 AuthTokenModel().delete(auth_token, c.user.user_id)
489 491 Session().commit()
490 492 h.flash(_("Auth token successfully deleted"), category='success')
491 493
492 494 return redirect(url('edit_user_auth_tokens', user_id=c.user.user_id))
493 495
494 496 @HasPermissionAllDecorator('hg.admin')
495 497 def edit_global_perms(self, user_id):
496 498 user_id = safe_int(user_id)
497 499 c.user = User.get_or_404(user_id)
498 500 if c.user.username == User.DEFAULT_USER:
499 501 h.flash(_("You can't edit this user"), category='warning')
500 502 return redirect(url('users'))
501 503
502 504 c.active = 'global_perms'
503 505
504 506 c.default_user = User.get_default_user()
505 507 defaults = c.user.get_dict()
506 508 defaults.update(c.default_user.get_default_perms(suffix='_inherited'))
507 509 defaults.update(c.default_user.get_default_perms())
508 510 defaults.update(c.user.get_default_perms())
509 511
510 512 return htmlfill.render(
511 513 render('admin/users/user_edit.html'),
512 514 defaults=defaults,
513 515 encoding="UTF-8",
514 516 force_defaults=False)
515 517
516 518 @HasPermissionAllDecorator('hg.admin')
517 519 @auth.CSRFRequired()
518 520 def update_global_perms(self, user_id):
519 521 """PUT /users_perm/user_id: Update an existing item"""
520 522 # url('user_perm', user_id=ID, method='put')
521 523 user_id = safe_int(user_id)
522 524 user = User.get_or_404(user_id)
523 525 c.active = 'global_perms'
524 526 try:
525 527 # first stage that verifies the checkbox
526 528 _form = UserIndividualPermissionsForm()
527 529 form_result = _form.to_python(dict(request.POST))
528 530 inherit_perms = form_result['inherit_default_permissions']
529 531 user.inherit_default_permissions = inherit_perms
530 532 Session().add(user)
531 533
532 534 if not inherit_perms:
533 535 # only update the individual ones if we un check the flag
534 536 _form = UserPermissionsForm(
535 537 [x[0] for x in c.repo_create_choices],
536 538 [x[0] for x in c.repo_create_on_write_choices],
537 539 [x[0] for x in c.repo_group_create_choices],
538 540 [x[0] for x in c.user_group_create_choices],
539 541 [x[0] for x in c.fork_choices],
540 542 [x[0] for x in c.inherit_default_permission_choices])()
541 543
542 544 form_result = _form.to_python(dict(request.POST))
543 545 form_result.update({'perm_user_id': user.user_id})
544 546
545 547 PermissionModel().update_user_permissions(form_result)
546 548
547 549 Session().commit()
548 550 h.flash(_('User global permissions updated successfully'),
549 551 category='success')
550 552
551 553 Session().commit()
552 554 except formencode.Invalid as errors:
553 555 defaults = errors.value
554 556 c.user = user
555 557 return htmlfill.render(
556 558 render('admin/users/user_edit.html'),
557 559 defaults=defaults,
558 560 errors=errors.error_dict or {},
559 561 prefix_error=False,
560 562 encoding="UTF-8",
561 563 force_defaults=False)
562 564 except Exception:
563 565 log.exception("Exception during permissions saving")
564 566 h.flash(_('An error occurred during permissions saving'),
565 567 category='error')
566 568 return redirect(url('edit_user_global_perms', user_id=user_id))
567 569
568 570 @HasPermissionAllDecorator('hg.admin')
569 571 def edit_perms_summary(self, user_id):
570 572 user_id = safe_int(user_id)
571 573 c.user = User.get_or_404(user_id)
572 574 if c.user.username == User.DEFAULT_USER:
573 575 h.flash(_("You can't edit this user"), category='warning')
574 576 return redirect(url('users'))
575 577
576 578 c.active = 'perms_summary'
577 579 c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr)
578 580
579 581 return render('admin/users/user_edit.html')
580 582
581 583 @HasPermissionAllDecorator('hg.admin')
582 584 def edit_emails(self, user_id):
583 585 user_id = safe_int(user_id)
584 586 c.user = User.get_or_404(user_id)
585 587 if c.user.username == User.DEFAULT_USER:
586 588 h.flash(_("You can't edit this user"), category='warning')
587 589 return redirect(url('users'))
588 590
589 591 c.active = 'emails'
590 592 c.user_email_map = UserEmailMap.query() \
591 593 .filter(UserEmailMap.user == c.user).all()
592 594
593 595 defaults = c.user.get_dict()
594 596 return htmlfill.render(
595 597 render('admin/users/user_edit.html'),
596 598 defaults=defaults,
597 599 encoding="UTF-8",
598 600 force_defaults=False)
599 601
600 602 @HasPermissionAllDecorator('hg.admin')
601 603 @auth.CSRFRequired()
602 604 def add_email(self, user_id):
603 605 """POST /user_emails:Add an existing item"""
604 606 # url('user_emails', user_id=ID, method='put')
605 607 user_id = safe_int(user_id)
606 608 c.user = User.get_or_404(user_id)
607 609
608 610 email = request.POST.get('new_email')
609 611 user_model = UserModel()
610 612
611 613 try:
612 614 user_model.add_extra_email(user_id, email)
613 615 Session().commit()
614 616 h.flash(_("Added new email address `%s` for user account") % email,
615 617 category='success')
616 618 except formencode.Invalid as error:
617 619 msg = error.error_dict['email']
618 620 h.flash(msg, category='error')
619 621 except Exception:
620 622 log.exception("Exception during email saving")
621 623 h.flash(_('An error occurred during email saving'),
622 624 category='error')
623 625 return redirect(url('edit_user_emails', user_id=user_id))
624 626
625 627 @HasPermissionAllDecorator('hg.admin')
626 628 @auth.CSRFRequired()
627 629 def delete_email(self, user_id):
628 630 """DELETE /user_emails_delete/user_id: Delete an existing item"""
629 631 # url('user_emails_delete', user_id=ID, method='delete')
630 632 user_id = safe_int(user_id)
631 633 c.user = User.get_or_404(user_id)
632 634 email_id = request.POST.get('del_email_id')
633 635 user_model = UserModel()
634 636 user_model.delete_extra_email(user_id, email_id)
635 637 Session().commit()
636 638 h.flash(_("Removed email address from user account"), category='success')
637 639 return redirect(url('edit_user_emails', user_id=user_id))
638 640
639 641 @HasPermissionAllDecorator('hg.admin')
640 642 def edit_ips(self, user_id):
641 643 user_id = safe_int(user_id)
642 644 c.user = User.get_or_404(user_id)
643 645 if c.user.username == User.DEFAULT_USER:
644 646 h.flash(_("You can't edit this user"), category='warning')
645 647 return redirect(url('users'))
646 648
647 649 c.active = 'ips'
648 650 c.user_ip_map = UserIpMap.query() \
649 651 .filter(UserIpMap.user == c.user).all()
650 652
651 653 c.inherit_default_ips = c.user.inherit_default_permissions
652 654 c.default_user_ip_map = UserIpMap.query() \
653 655 .filter(UserIpMap.user == User.get_default_user()).all()
654 656
655 657 defaults = c.user.get_dict()
656 658 return htmlfill.render(
657 659 render('admin/users/user_edit.html'),
658 660 defaults=defaults,
659 661 encoding="UTF-8",
660 662 force_defaults=False)
661 663
662 664 @HasPermissionAllDecorator('hg.admin')
663 665 @auth.CSRFRequired()
664 666 def add_ip(self, user_id):
665 667 """POST /user_ips:Add an existing item"""
666 668 # url('user_ips', user_id=ID, method='put')
667 669
668 670 user_id = safe_int(user_id)
669 671 c.user = User.get_or_404(user_id)
670 672 user_model = UserModel()
671 673 try:
672 674 ip_list = user_model.parse_ip_range(request.POST.get('new_ip'))
673 675 except Exception as e:
674 676 ip_list = []
675 677 log.exception("Exception during ip saving")
676 678 h.flash(_('An error occurred during ip saving:%s' % (e,)),
677 679 category='error')
678 680
679 681 desc = request.POST.get('description')
680 682 added = []
681 683 for ip in ip_list:
682 684 try:
683 685 user_model.add_extra_ip(user_id, ip, desc)
684 686 Session().commit()
685 687 added.append(ip)
686 688 except formencode.Invalid as error:
687 689 msg = error.error_dict['ip']
688 690 h.flash(msg, category='error')
689 691 except Exception:
690 692 log.exception("Exception during ip saving")
691 693 h.flash(_('An error occurred during ip saving'),
692 694 category='error')
693 695 if added:
694 696 h.flash(
695 697 _("Added ips %s to user whitelist") % (', '.join(ip_list), ),
696 698 category='success')
697 699 if 'default_user' in request.POST:
698 700 return redirect(url('admin_permissions_ips'))
699 701 return redirect(url('edit_user_ips', user_id=user_id))
700 702
701 703 @HasPermissionAllDecorator('hg.admin')
702 704 @auth.CSRFRequired()
703 705 def delete_ip(self, user_id):
704 706 """DELETE /user_ips_delete/user_id: Delete an existing item"""
705 707 # url('user_ips_delete', user_id=ID, method='delete')
706 708 user_id = safe_int(user_id)
707 709 c.user = User.get_or_404(user_id)
708 710
709 711 ip_id = request.POST.get('del_ip_id')
710 712 user_model = UserModel()
711 713 user_model.delete_extra_ip(user_id, ip_id)
712 714 Session().commit()
713 715 h.flash(_("Removed ip address from user whitelist"), category='success')
714 716
715 717 if 'default_user' in request.POST:
716 718 return redirect(url('admin_permissions_ips'))
717 719 return redirect(url('edit_user_ips', user_id=user_id))
General Comments 0
You need to be logged in to leave comments. Login now