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