##// END OF EJS Templates
i18n: expose custom name to catch the translation strings.
marcink -
r1098:5d0049e7 default
parent child
Show More
@@ -1,249 +1,249
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 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 """
22 """
23 permissions controller for RhodeCode Enterprise
23 permissions controller for RhodeCode Enterprise
24 """
24 """
25
25
26
26
27 import logging
27 import logging
28
28
29 import formencode
29 import formencode
30 from formencode import htmlfill
30 from formencode import htmlfill
31 from pylons import request, tmpl_context as c, url
31 from pylons import request, tmpl_context as c, url
32 from pylons.controllers.util import redirect
32 from pylons.controllers.util import redirect
33 from pylons.i18n.translation import _
33 from pylons.i18n.translation import _
34
34
35 from rhodecode.lib import helpers as h
35 from rhodecode.lib import helpers as h
36 from rhodecode.lib import auth
36 from rhodecode.lib import auth
37 from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator)
37 from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator)
38 from rhodecode.lib.base import BaseController, render
38 from rhodecode.lib.base import BaseController, render
39 from rhodecode.model.db import User, UserIpMap
39 from rhodecode.model.db import User, UserIpMap
40 from rhodecode.model.forms import (
40 from rhodecode.model.forms import (
41 ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm)
41 ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm)
42 from rhodecode.model.meta import Session
42 from rhodecode.model.meta import Session
43 from rhodecode.model.permission import PermissionModel
43 from rhodecode.model.permission import PermissionModel
44 from rhodecode.model.settings import SettingsModel
44 from rhodecode.model.settings import SettingsModel
45
45
46 log = logging.getLogger(__name__)
46 log = logging.getLogger(__name__)
47
47
48
48
49 class PermissionsController(BaseController):
49 class PermissionsController(BaseController):
50 """REST Controller styled on the Atom Publishing Protocol"""
50 """REST Controller styled on the Atom Publishing Protocol"""
51 # To properly map this controller, ensure your config/routing.py
51 # To properly map this controller, ensure your config/routing.py
52 # file has a resource setup:
52 # file has a resource setup:
53 # map.resource('permission', 'permissions')
53 # map.resource('permission', 'permissions')
54
54
55 @LoginRequired()
55 @LoginRequired()
56 def __before__(self):
56 def __before__(self):
57 super(PermissionsController, self).__before__()
57 super(PermissionsController, self).__before__()
58
58
59 def __load_data(self):
59 def __load_data(self):
60 PermissionModel().set_global_permission_choices(c, translator=_)
60 PermissionModel().set_global_permission_choices(c, gettext_translator=_)
61
61
62 @HasPermissionAllDecorator('hg.admin')
62 @HasPermissionAllDecorator('hg.admin')
63 def permission_application(self):
63 def permission_application(self):
64 c.active = 'application'
64 c.active = 'application'
65 self.__load_data()
65 self.__load_data()
66
66
67 c.user = User.get_default_user()
67 c.user = User.get_default_user()
68
68
69 # TODO: johbo: The default user might be based on outdated state which
69 # TODO: johbo: The default user might be based on outdated state which
70 # has been loaded from the cache. A call to refresh() ensures that the
70 # has been loaded from the cache. A call to refresh() ensures that the
71 # latest state from the database is used.
71 # latest state from the database is used.
72 Session().refresh(c.user)
72 Session().refresh(c.user)
73
73
74 app_settings = SettingsModel().get_all_settings()
74 app_settings = SettingsModel().get_all_settings()
75 defaults = {
75 defaults = {
76 'anonymous': c.user.active,
76 'anonymous': c.user.active,
77 'default_register_message': app_settings.get(
77 'default_register_message': app_settings.get(
78 'rhodecode_register_message')
78 'rhodecode_register_message')
79 }
79 }
80 defaults.update(c.user.get_default_perms())
80 defaults.update(c.user.get_default_perms())
81
81
82 return htmlfill.render(
82 return htmlfill.render(
83 render('admin/permissions/permissions.html'),
83 render('admin/permissions/permissions.html'),
84 defaults=defaults,
84 defaults=defaults,
85 encoding="UTF-8",
85 encoding="UTF-8",
86 force_defaults=False)
86 force_defaults=False)
87
87
88 @HasPermissionAllDecorator('hg.admin')
88 @HasPermissionAllDecorator('hg.admin')
89 @auth.CSRFRequired()
89 @auth.CSRFRequired()
90 def permission_application_update(self):
90 def permission_application_update(self):
91 c.active = 'application'
91 c.active = 'application'
92 self.__load_data()
92 self.__load_data()
93 _form = ApplicationPermissionsForm(
93 _form = ApplicationPermissionsForm(
94 [x[0] for x in c.register_choices],
94 [x[0] for x in c.register_choices],
95 [x[0] for x in c.password_reset_choices],
95 [x[0] for x in c.password_reset_choices],
96 [x[0] for x in c.extern_activate_choices])()
96 [x[0] for x in c.extern_activate_choices])()
97
97
98 try:
98 try:
99 form_result = _form.to_python(dict(request.POST))
99 form_result = _form.to_python(dict(request.POST))
100 form_result.update({'perm_user_name': User.DEFAULT_USER})
100 form_result.update({'perm_user_name': User.DEFAULT_USER})
101 PermissionModel().update_application_permissions(form_result)
101 PermissionModel().update_application_permissions(form_result)
102
102
103 settings = [
103 settings = [
104 ('register_message', 'default_register_message'),
104 ('register_message', 'default_register_message'),
105 ]
105 ]
106 for setting, form_key in settings:
106 for setting, form_key in settings:
107 sett = SettingsModel().create_or_update_setting(
107 sett = SettingsModel().create_or_update_setting(
108 setting, form_result[form_key])
108 setting, form_result[form_key])
109 Session().add(sett)
109 Session().add(sett)
110
110
111 Session().commit()
111 Session().commit()
112 h.flash(_('Application permissions updated successfully'),
112 h.flash(_('Application permissions updated successfully'),
113 category='success')
113 category='success')
114
114
115 except formencode.Invalid as errors:
115 except formencode.Invalid as errors:
116 defaults = errors.value
116 defaults = errors.value
117
117
118 return htmlfill.render(
118 return htmlfill.render(
119 render('admin/permissions/permissions.html'),
119 render('admin/permissions/permissions.html'),
120 defaults=defaults,
120 defaults=defaults,
121 errors=errors.error_dict or {},
121 errors=errors.error_dict or {},
122 prefix_error=False,
122 prefix_error=False,
123 encoding="UTF-8",
123 encoding="UTF-8",
124 force_defaults=False)
124 force_defaults=False)
125 except Exception:
125 except Exception:
126 log.exception("Exception during update of permissions")
126 log.exception("Exception during update of permissions")
127 h.flash(_('Error occurred during update of permissions'),
127 h.flash(_('Error occurred during update of permissions'),
128 category='error')
128 category='error')
129
129
130 return redirect(url('admin_permissions_application'))
130 return redirect(url('admin_permissions_application'))
131
131
132 @HasPermissionAllDecorator('hg.admin')
132 @HasPermissionAllDecorator('hg.admin')
133 def permission_objects(self):
133 def permission_objects(self):
134 c.active = 'objects'
134 c.active = 'objects'
135 self.__load_data()
135 self.__load_data()
136 c.user = User.get_default_user()
136 c.user = User.get_default_user()
137 defaults = {}
137 defaults = {}
138 defaults.update(c.user.get_default_perms())
138 defaults.update(c.user.get_default_perms())
139 return htmlfill.render(
139 return htmlfill.render(
140 render('admin/permissions/permissions.html'),
140 render('admin/permissions/permissions.html'),
141 defaults=defaults,
141 defaults=defaults,
142 encoding="UTF-8",
142 encoding="UTF-8",
143 force_defaults=False)
143 force_defaults=False)
144
144
145 @HasPermissionAllDecorator('hg.admin')
145 @HasPermissionAllDecorator('hg.admin')
146 @auth.CSRFRequired()
146 @auth.CSRFRequired()
147 def permission_objects_update(self):
147 def permission_objects_update(self):
148 c.active = 'objects'
148 c.active = 'objects'
149 self.__load_data()
149 self.__load_data()
150 _form = ObjectPermissionsForm(
150 _form = ObjectPermissionsForm(
151 [x[0] for x in c.repo_perms_choices],
151 [x[0] for x in c.repo_perms_choices],
152 [x[0] for x in c.group_perms_choices],
152 [x[0] for x in c.group_perms_choices],
153 [x[0] for x in c.user_group_perms_choices])()
153 [x[0] for x in c.user_group_perms_choices])()
154
154
155 try:
155 try:
156 form_result = _form.to_python(dict(request.POST))
156 form_result = _form.to_python(dict(request.POST))
157 form_result.update({'perm_user_name': User.DEFAULT_USER})
157 form_result.update({'perm_user_name': User.DEFAULT_USER})
158 PermissionModel().update_object_permissions(form_result)
158 PermissionModel().update_object_permissions(form_result)
159
159
160 Session().commit()
160 Session().commit()
161 h.flash(_('Object permissions updated successfully'),
161 h.flash(_('Object permissions updated successfully'),
162 category='success')
162 category='success')
163
163
164 except formencode.Invalid as errors:
164 except formencode.Invalid as errors:
165 defaults = errors.value
165 defaults = errors.value
166
166
167 return htmlfill.render(
167 return htmlfill.render(
168 render('admin/permissions/permissions.html'),
168 render('admin/permissions/permissions.html'),
169 defaults=defaults,
169 defaults=defaults,
170 errors=errors.error_dict or {},
170 errors=errors.error_dict or {},
171 prefix_error=False,
171 prefix_error=False,
172 encoding="UTF-8",
172 encoding="UTF-8",
173 force_defaults=False)
173 force_defaults=False)
174 except Exception:
174 except Exception:
175 log.exception("Exception during update of permissions")
175 log.exception("Exception during update of permissions")
176 h.flash(_('Error occurred during update of permissions'),
176 h.flash(_('Error occurred during update of permissions'),
177 category='error')
177 category='error')
178
178
179 return redirect(url('admin_permissions_object'))
179 return redirect(url('admin_permissions_object'))
180
180
181 @HasPermissionAllDecorator('hg.admin')
181 @HasPermissionAllDecorator('hg.admin')
182 def permission_global(self):
182 def permission_global(self):
183 c.active = 'global'
183 c.active = 'global'
184 self.__load_data()
184 self.__load_data()
185
185
186 c.user = User.get_default_user()
186 c.user = User.get_default_user()
187 defaults = {}
187 defaults = {}
188 defaults.update(c.user.get_default_perms())
188 defaults.update(c.user.get_default_perms())
189
189
190 return htmlfill.render(
190 return htmlfill.render(
191 render('admin/permissions/permissions.html'),
191 render('admin/permissions/permissions.html'),
192 defaults=defaults,
192 defaults=defaults,
193 encoding="UTF-8",
193 encoding="UTF-8",
194 force_defaults=False)
194 force_defaults=False)
195
195
196 @HasPermissionAllDecorator('hg.admin')
196 @HasPermissionAllDecorator('hg.admin')
197 @auth.CSRFRequired()
197 @auth.CSRFRequired()
198 def permission_global_update(self):
198 def permission_global_update(self):
199 c.active = 'global'
199 c.active = 'global'
200 self.__load_data()
200 self.__load_data()
201 _form = UserPermissionsForm(
201 _form = UserPermissionsForm(
202 [x[0] for x in c.repo_create_choices],
202 [x[0] for x in c.repo_create_choices],
203 [x[0] for x in c.repo_create_on_write_choices],
203 [x[0] for x in c.repo_create_on_write_choices],
204 [x[0] for x in c.repo_group_create_choices],
204 [x[0] for x in c.repo_group_create_choices],
205 [x[0] for x in c.user_group_create_choices],
205 [x[0] for x in c.user_group_create_choices],
206 [x[0] for x in c.fork_choices],
206 [x[0] for x in c.fork_choices],
207 [x[0] for x in c.inherit_default_permission_choices])()
207 [x[0] for x in c.inherit_default_permission_choices])()
208
208
209 try:
209 try:
210 form_result = _form.to_python(dict(request.POST))
210 form_result = _form.to_python(dict(request.POST))
211 form_result.update({'perm_user_name': User.DEFAULT_USER})
211 form_result.update({'perm_user_name': User.DEFAULT_USER})
212 PermissionModel().update_user_permissions(form_result)
212 PermissionModel().update_user_permissions(form_result)
213
213
214 Session().commit()
214 Session().commit()
215 h.flash(_('Global permissions updated successfully'),
215 h.flash(_('Global permissions updated successfully'),
216 category='success')
216 category='success')
217
217
218 except formencode.Invalid as errors:
218 except formencode.Invalid as errors:
219 defaults = errors.value
219 defaults = errors.value
220
220
221 return htmlfill.render(
221 return htmlfill.render(
222 render('admin/permissions/permissions.html'),
222 render('admin/permissions/permissions.html'),
223 defaults=defaults,
223 defaults=defaults,
224 errors=errors.error_dict or {},
224 errors=errors.error_dict or {},
225 prefix_error=False,
225 prefix_error=False,
226 encoding="UTF-8",
226 encoding="UTF-8",
227 force_defaults=False)
227 force_defaults=False)
228 except Exception:
228 except Exception:
229 log.exception("Exception during update of permissions")
229 log.exception("Exception during update of permissions")
230 h.flash(_('Error occurred during update of permissions'),
230 h.flash(_('Error occurred during update of permissions'),
231 category='error')
231 category='error')
232
232
233 return redirect(url('admin_permissions_global'))
233 return redirect(url('admin_permissions_global'))
234
234
235 @HasPermissionAllDecorator('hg.admin')
235 @HasPermissionAllDecorator('hg.admin')
236 def permission_ips(self):
236 def permission_ips(self):
237 c.active = 'ips'
237 c.active = 'ips'
238 c.user = User.get_default_user()
238 c.user = User.get_default_user()
239 c.user_ip_map = (
239 c.user_ip_map = (
240 UserIpMap.query().filter(UserIpMap.user == c.user).all())
240 UserIpMap.query().filter(UserIpMap.user == c.user).all())
241
241
242 return render('admin/permissions/permissions.html')
242 return render('admin/permissions/permissions.html')
243
243
244 @HasPermissionAllDecorator('hg.admin')
244 @HasPermissionAllDecorator('hg.admin')
245 def permission_perms(self):
245 def permission_perms(self):
246 c.active = 'perms'
246 c.active = 'perms'
247 c.user = User.get_default_user()
247 c.user = User.get_default_user()
248 c.perm_user = c.user.AuthUser
248 c.perm_user = c.user.AuthUser
249 return render('admin/permissions/permissions.html')
249 return render('admin/permissions/permissions.html')
@@ -1,487 +1,487
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-2016 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 User Groups crud controller for pylons
22 User Groups crud controller for pylons
23 """
23 """
24
24
25 import logging
25 import logging
26 import formencode
26 import formencode
27
27
28 import peppercorn
28 import peppercorn
29 from formencode import htmlfill
29 from formencode import htmlfill
30 from pylons import request, tmpl_context as c, url, config
30 from pylons import request, tmpl_context as c, url, config
31 from pylons.controllers.util import redirect
31 from pylons.controllers.util import redirect
32 from pylons.i18n.translation import _
32 from pylons.i18n.translation import _
33
33
34 from sqlalchemy.orm import joinedload
34 from sqlalchemy.orm import joinedload
35
35
36 from rhodecode.lib import auth
36 from rhodecode.lib import auth
37 from rhodecode.lib import helpers as h
37 from rhodecode.lib import helpers as h
38 from rhodecode.lib.exceptions import UserGroupAssignedException,\
38 from rhodecode.lib.exceptions import UserGroupAssignedException,\
39 RepoGroupAssignmentError
39 RepoGroupAssignmentError
40 from rhodecode.lib.utils import jsonify, action_logger
40 from rhodecode.lib.utils import jsonify, action_logger
41 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
41 from rhodecode.lib.utils2 import safe_unicode, str2bool, safe_int
42 from rhodecode.lib.auth import (
42 from rhodecode.lib.auth import (
43 LoginRequired, NotAnonymous, HasUserGroupPermissionAnyDecorator,
43 LoginRequired, NotAnonymous, HasUserGroupPermissionAnyDecorator,
44 HasPermissionAnyDecorator, XHRRequired)
44 HasPermissionAnyDecorator, XHRRequired)
45 from rhodecode.lib.base import BaseController, render
45 from rhodecode.lib.base import BaseController, render
46 from rhodecode.model.permission import PermissionModel
46 from rhodecode.model.permission import PermissionModel
47 from rhodecode.model.scm import UserGroupList
47 from rhodecode.model.scm import UserGroupList
48 from rhodecode.model.user_group import UserGroupModel
48 from rhodecode.model.user_group import UserGroupModel
49 from rhodecode.model.db import (
49 from rhodecode.model.db import (
50 User, UserGroup, UserGroupRepoToPerm, UserGroupRepoGroupToPerm)
50 User, UserGroup, UserGroupRepoToPerm, UserGroupRepoGroupToPerm)
51 from rhodecode.model.forms import (
51 from rhodecode.model.forms import (
52 UserGroupForm, UserGroupPermsForm, UserIndividualPermissionsForm,
52 UserGroupForm, UserGroupPermsForm, UserIndividualPermissionsForm,
53 UserPermissionsForm)
53 UserPermissionsForm)
54 from rhodecode.model.meta import Session
54 from rhodecode.model.meta import Session
55 from rhodecode.lib.utils import action_logger
55 from rhodecode.lib.utils import action_logger
56 from rhodecode.lib.ext_json import json
56 from rhodecode.lib.ext_json import json
57
57
58 log = logging.getLogger(__name__)
58 log = logging.getLogger(__name__)
59
59
60
60
61 class UserGroupsController(BaseController):
61 class UserGroupsController(BaseController):
62 """REST Controller styled on the Atom Publishing Protocol"""
62 """REST Controller styled on the Atom Publishing Protocol"""
63
63
64 @LoginRequired()
64 @LoginRequired()
65 def __before__(self):
65 def __before__(self):
66 super(UserGroupsController, self).__before__()
66 super(UserGroupsController, self).__before__()
67 c.available_permissions = config['available_permissions']
67 c.available_permissions = config['available_permissions']
68 PermissionModel().set_global_permission_choices(c, translator=_)
68 PermissionModel().set_global_permission_choices(c, gettext_translator=_)
69
69
70 def __load_data(self, user_group_id):
70 def __load_data(self, user_group_id):
71 c.group_members_obj = [x.user for x in c.user_group.members]
71 c.group_members_obj = [x.user for x in c.user_group.members]
72 c.group_members_obj.sort(key=lambda u: u.username.lower())
72 c.group_members_obj.sort(key=lambda u: u.username.lower())
73 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
73 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
74
74
75 def __load_defaults(self, user_group_id):
75 def __load_defaults(self, user_group_id):
76 """
76 """
77 Load defaults settings for edit, and update
77 Load defaults settings for edit, and update
78
78
79 :param user_group_id:
79 :param user_group_id:
80 """
80 """
81 user_group = UserGroup.get_or_404(user_group_id)
81 user_group = UserGroup.get_or_404(user_group_id)
82 data = user_group.get_dict()
82 data = user_group.get_dict()
83 # fill owner
83 # fill owner
84 if user_group.user:
84 if user_group.user:
85 data.update({'user': user_group.user.username})
85 data.update({'user': user_group.user.username})
86 else:
86 else:
87 replacement_user = User.get_first_super_admin().username
87 replacement_user = User.get_first_super_admin().username
88 data.update({'user': replacement_user})
88 data.update({'user': replacement_user})
89 return data
89 return data
90
90
91 def _revoke_perms_on_yourself(self, form_result):
91 def _revoke_perms_on_yourself(self, form_result):
92 _updates = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
92 _updates = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
93 form_result['perm_updates'])
93 form_result['perm_updates'])
94 _additions = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
94 _additions = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
95 form_result['perm_additions'])
95 form_result['perm_additions'])
96 _deletions = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
96 _deletions = filter(lambda u: c.rhodecode_user.user_id == int(u[0]),
97 form_result['perm_deletions'])
97 form_result['perm_deletions'])
98 admin_perm = 'usergroup.admin'
98 admin_perm = 'usergroup.admin'
99 if _updates and _updates[0][1] != admin_perm or \
99 if _updates and _updates[0][1] != admin_perm or \
100 _additions and _additions[0][1] != admin_perm or \
100 _additions and _additions[0][1] != admin_perm or \
101 _deletions and _deletions[0][1] != admin_perm:
101 _deletions and _deletions[0][1] != admin_perm:
102 return True
102 return True
103 return False
103 return False
104
104
105 # permission check inside
105 # permission check inside
106 @NotAnonymous()
106 @NotAnonymous()
107 def index(self):
107 def index(self):
108 """GET /users_groups: All items in the collection"""
108 """GET /users_groups: All items in the collection"""
109 # url('users_groups')
109 # url('users_groups')
110
110
111 from rhodecode.lib.utils import PartialRenderer
111 from rhodecode.lib.utils import PartialRenderer
112 _render = PartialRenderer('data_table/_dt_elements.html')
112 _render = PartialRenderer('data_table/_dt_elements.html')
113
113
114 def user_group_name(user_group_id, user_group_name):
114 def user_group_name(user_group_id, user_group_name):
115 return _render("user_group_name", user_group_id, user_group_name)
115 return _render("user_group_name", user_group_id, user_group_name)
116
116
117 def user_group_actions(user_group_id, user_group_name):
117 def user_group_actions(user_group_id, user_group_name):
118 return _render("user_group_actions", user_group_id, user_group_name)
118 return _render("user_group_actions", user_group_id, user_group_name)
119
119
120 ## json generate
120 ## json generate
121 group_iter = UserGroupList(UserGroup.query().all(),
121 group_iter = UserGroupList(UserGroup.query().all(),
122 perm_set=['usergroup.admin'])
122 perm_set=['usergroup.admin'])
123
123
124 user_groups_data = []
124 user_groups_data = []
125 for user_gr in group_iter:
125 for user_gr in group_iter:
126 user_groups_data.append({
126 user_groups_data.append({
127 "group_name": user_group_name(
127 "group_name": user_group_name(
128 user_gr.users_group_id, h.escape(user_gr.users_group_name)),
128 user_gr.users_group_id, h.escape(user_gr.users_group_name)),
129 "group_name_raw": user_gr.users_group_name,
129 "group_name_raw": user_gr.users_group_name,
130 "desc": h.escape(user_gr.user_group_description),
130 "desc": h.escape(user_gr.user_group_description),
131 "members": len(user_gr.members),
131 "members": len(user_gr.members),
132 "active": h.bool2icon(user_gr.users_group_active),
132 "active": h.bool2icon(user_gr.users_group_active),
133 "owner": h.escape(h.link_to_user(user_gr.user.username)),
133 "owner": h.escape(h.link_to_user(user_gr.user.username)),
134 "action": user_group_actions(
134 "action": user_group_actions(
135 user_gr.users_group_id, user_gr.users_group_name)
135 user_gr.users_group_id, user_gr.users_group_name)
136 })
136 })
137
137
138 c.data = json.dumps(user_groups_data)
138 c.data = json.dumps(user_groups_data)
139 return render('admin/user_groups/user_groups.html')
139 return render('admin/user_groups/user_groups.html')
140
140
141 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
141 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
142 @auth.CSRFRequired()
142 @auth.CSRFRequired()
143 def create(self):
143 def create(self):
144 """POST /users_groups: Create a new item"""
144 """POST /users_groups: Create a new item"""
145 # url('users_groups')
145 # url('users_groups')
146
146
147 users_group_form = UserGroupForm()()
147 users_group_form = UserGroupForm()()
148 try:
148 try:
149 form_result = users_group_form.to_python(dict(request.POST))
149 form_result = users_group_form.to_python(dict(request.POST))
150 user_group = UserGroupModel().create(
150 user_group = UserGroupModel().create(
151 name=form_result['users_group_name'],
151 name=form_result['users_group_name'],
152 description=form_result['user_group_description'],
152 description=form_result['user_group_description'],
153 owner=c.rhodecode_user.user_id,
153 owner=c.rhodecode_user.user_id,
154 active=form_result['users_group_active'])
154 active=form_result['users_group_active'])
155 Session().flush()
155 Session().flush()
156
156
157 user_group_name = form_result['users_group_name']
157 user_group_name = form_result['users_group_name']
158 action_logger(c.rhodecode_user,
158 action_logger(c.rhodecode_user,
159 'admin_created_users_group:%s' % user_group_name,
159 'admin_created_users_group:%s' % user_group_name,
160 None, self.ip_addr, self.sa)
160 None, self.ip_addr, self.sa)
161 user_group_link = h.link_to(h.escape(user_group_name),
161 user_group_link = h.link_to(h.escape(user_group_name),
162 url('edit_users_group',
162 url('edit_users_group',
163 user_group_id=user_group.users_group_id))
163 user_group_id=user_group.users_group_id))
164 h.flash(h.literal(_('Created user group %(user_group_link)s')
164 h.flash(h.literal(_('Created user group %(user_group_link)s')
165 % {'user_group_link': user_group_link}),
165 % {'user_group_link': user_group_link}),
166 category='success')
166 category='success')
167 Session().commit()
167 Session().commit()
168 except formencode.Invalid as errors:
168 except formencode.Invalid as errors:
169 return htmlfill.render(
169 return htmlfill.render(
170 render('admin/user_groups/user_group_add.html'),
170 render('admin/user_groups/user_group_add.html'),
171 defaults=errors.value,
171 defaults=errors.value,
172 errors=errors.error_dict or {},
172 errors=errors.error_dict or {},
173 prefix_error=False,
173 prefix_error=False,
174 encoding="UTF-8",
174 encoding="UTF-8",
175 force_defaults=False)
175 force_defaults=False)
176 except Exception:
176 except Exception:
177 log.exception("Exception creating user group")
177 log.exception("Exception creating user group")
178 h.flash(_('Error occurred during creation of user group %s') \
178 h.flash(_('Error occurred during creation of user group %s') \
179 % request.POST.get('users_group_name'), category='error')
179 % request.POST.get('users_group_name'), category='error')
180
180
181 return redirect(
181 return redirect(
182 url('edit_users_group', user_group_id=user_group.users_group_id))
182 url('edit_users_group', user_group_id=user_group.users_group_id))
183
183
184 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
184 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
185 def new(self):
185 def new(self):
186 """GET /user_groups/new: Form to create a new item"""
186 """GET /user_groups/new: Form to create a new item"""
187 # url('new_users_group')
187 # url('new_users_group')
188 return render('admin/user_groups/user_group_add.html')
188 return render('admin/user_groups/user_group_add.html')
189
189
190 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
190 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
191 @auth.CSRFRequired()
191 @auth.CSRFRequired()
192 def update(self, user_group_id):
192 def update(self, user_group_id):
193 """PUT /user_groups/user_group_id: Update an existing item"""
193 """PUT /user_groups/user_group_id: Update an existing item"""
194 # Forms posted to this method should contain a hidden field:
194 # Forms posted to this method should contain a hidden field:
195 # <input type="hidden" name="_method" value="PUT" />
195 # <input type="hidden" name="_method" value="PUT" />
196 # Or using helpers:
196 # Or using helpers:
197 # h.form(url('users_group', user_group_id=ID),
197 # h.form(url('users_group', user_group_id=ID),
198 # method='put')
198 # method='put')
199 # url('users_group', user_group_id=ID)
199 # url('users_group', user_group_id=ID)
200
200
201 user_group_id = safe_int(user_group_id)
201 user_group_id = safe_int(user_group_id)
202 c.user_group = UserGroup.get_or_404(user_group_id)
202 c.user_group = UserGroup.get_or_404(user_group_id)
203 c.active = 'settings'
203 c.active = 'settings'
204 self.__load_data(user_group_id)
204 self.__load_data(user_group_id)
205
205
206 users_group_form = UserGroupForm(
206 users_group_form = UserGroupForm(
207 edit=True, old_data=c.user_group.get_dict(), allow_disabled=True)()
207 edit=True, old_data=c.user_group.get_dict(), allow_disabled=True)()
208
208
209 try:
209 try:
210 form_result = users_group_form.to_python(request.POST)
210 form_result = users_group_form.to_python(request.POST)
211 pstruct = peppercorn.parse(request.POST.items())
211 pstruct = peppercorn.parse(request.POST.items())
212 form_result['users_group_members'] = pstruct['user_group_members']
212 form_result['users_group_members'] = pstruct['user_group_members']
213
213
214 UserGroupModel().update(c.user_group, form_result)
214 UserGroupModel().update(c.user_group, form_result)
215 updated_user_group = form_result['users_group_name']
215 updated_user_group = form_result['users_group_name']
216 action_logger(c.rhodecode_user,
216 action_logger(c.rhodecode_user,
217 'admin_updated_users_group:%s' % updated_user_group,
217 'admin_updated_users_group:%s' % updated_user_group,
218 None, self.ip_addr, self.sa)
218 None, self.ip_addr, self.sa)
219 h.flash(_('Updated user group %s') % updated_user_group,
219 h.flash(_('Updated user group %s') % updated_user_group,
220 category='success')
220 category='success')
221 Session().commit()
221 Session().commit()
222 except formencode.Invalid as errors:
222 except formencode.Invalid as errors:
223 defaults = errors.value
223 defaults = errors.value
224 e = errors.error_dict or {}
224 e = errors.error_dict or {}
225
225
226 return htmlfill.render(
226 return htmlfill.render(
227 render('admin/user_groups/user_group_edit.html'),
227 render('admin/user_groups/user_group_edit.html'),
228 defaults=defaults,
228 defaults=defaults,
229 errors=e,
229 errors=e,
230 prefix_error=False,
230 prefix_error=False,
231 encoding="UTF-8",
231 encoding="UTF-8",
232 force_defaults=False)
232 force_defaults=False)
233 except Exception:
233 except Exception:
234 log.exception("Exception during update of user group")
234 log.exception("Exception during update of user group")
235 h.flash(_('Error occurred during update of user group %s')
235 h.flash(_('Error occurred during update of user group %s')
236 % request.POST.get('users_group_name'), category='error')
236 % request.POST.get('users_group_name'), category='error')
237
237
238 return redirect(url('edit_users_group', user_group_id=user_group_id))
238 return redirect(url('edit_users_group', user_group_id=user_group_id))
239
239
240 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
240 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
241 @auth.CSRFRequired()
241 @auth.CSRFRequired()
242 def delete(self, user_group_id):
242 def delete(self, user_group_id):
243 """DELETE /user_groups/user_group_id: Delete an existing item"""
243 """DELETE /user_groups/user_group_id: Delete an existing item"""
244 # Forms posted to this method should contain a hidden field:
244 # Forms posted to this method should contain a hidden field:
245 # <input type="hidden" name="_method" value="DELETE" />
245 # <input type="hidden" name="_method" value="DELETE" />
246 # Or using helpers:
246 # Or using helpers:
247 # h.form(url('users_group', user_group_id=ID),
247 # h.form(url('users_group', user_group_id=ID),
248 # method='delete')
248 # method='delete')
249 # url('users_group', user_group_id=ID)
249 # url('users_group', user_group_id=ID)
250 user_group_id = safe_int(user_group_id)
250 user_group_id = safe_int(user_group_id)
251 c.user_group = UserGroup.get_or_404(user_group_id)
251 c.user_group = UserGroup.get_or_404(user_group_id)
252 force = str2bool(request.POST.get('force'))
252 force = str2bool(request.POST.get('force'))
253
253
254 try:
254 try:
255 UserGroupModel().delete(c.user_group, force=force)
255 UserGroupModel().delete(c.user_group, force=force)
256 Session().commit()
256 Session().commit()
257 h.flash(_('Successfully deleted user group'), category='success')
257 h.flash(_('Successfully deleted user group'), category='success')
258 except UserGroupAssignedException as e:
258 except UserGroupAssignedException as e:
259 h.flash(str(e), category='error')
259 h.flash(str(e), category='error')
260 except Exception:
260 except Exception:
261 log.exception("Exception during deletion of user group")
261 log.exception("Exception during deletion of user group")
262 h.flash(_('An error occurred during deletion of user group'),
262 h.flash(_('An error occurred during deletion of user group'),
263 category='error')
263 category='error')
264 return redirect(url('users_groups'))
264 return redirect(url('users_groups'))
265
265
266 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
266 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
267 def edit(self, user_group_id):
267 def edit(self, user_group_id):
268 """GET /user_groups/user_group_id/edit: Form to edit an existing item"""
268 """GET /user_groups/user_group_id/edit: Form to edit an existing item"""
269 # url('edit_users_group', user_group_id=ID)
269 # url('edit_users_group', user_group_id=ID)
270
270
271 user_group_id = safe_int(user_group_id)
271 user_group_id = safe_int(user_group_id)
272 c.user_group = UserGroup.get_or_404(user_group_id)
272 c.user_group = UserGroup.get_or_404(user_group_id)
273 c.active = 'settings'
273 c.active = 'settings'
274 self.__load_data(user_group_id)
274 self.__load_data(user_group_id)
275
275
276 defaults = self.__load_defaults(user_group_id)
276 defaults = self.__load_defaults(user_group_id)
277
277
278 return htmlfill.render(
278 return htmlfill.render(
279 render('admin/user_groups/user_group_edit.html'),
279 render('admin/user_groups/user_group_edit.html'),
280 defaults=defaults,
280 defaults=defaults,
281 encoding="UTF-8",
281 encoding="UTF-8",
282 force_defaults=False
282 force_defaults=False
283 )
283 )
284
284
285 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
285 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
286 def edit_perms(self, user_group_id):
286 def edit_perms(self, user_group_id):
287 user_group_id = safe_int(user_group_id)
287 user_group_id = safe_int(user_group_id)
288 c.user_group = UserGroup.get_or_404(user_group_id)
288 c.user_group = UserGroup.get_or_404(user_group_id)
289 c.active = 'perms'
289 c.active = 'perms'
290
290
291 defaults = {}
291 defaults = {}
292 # fill user group users
292 # fill user group users
293 for p in c.user_group.user_user_group_to_perm:
293 for p in c.user_group.user_user_group_to_perm:
294 defaults.update({'u_perm_%s' % p.user.user_id:
294 defaults.update({'u_perm_%s' % p.user.user_id:
295 p.permission.permission_name})
295 p.permission.permission_name})
296
296
297 for p in c.user_group.user_group_user_group_to_perm:
297 for p in c.user_group.user_group_user_group_to_perm:
298 defaults.update({'g_perm_%s' % p.user_group.users_group_id:
298 defaults.update({'g_perm_%s' % p.user_group.users_group_id:
299 p.permission.permission_name})
299 p.permission.permission_name})
300
300
301 return htmlfill.render(
301 return htmlfill.render(
302 render('admin/user_groups/user_group_edit.html'),
302 render('admin/user_groups/user_group_edit.html'),
303 defaults=defaults,
303 defaults=defaults,
304 encoding="UTF-8",
304 encoding="UTF-8",
305 force_defaults=False
305 force_defaults=False
306 )
306 )
307
307
308 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
308 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
309 @auth.CSRFRequired()
309 @auth.CSRFRequired()
310 def update_perms(self, user_group_id):
310 def update_perms(self, user_group_id):
311 """
311 """
312 grant permission for given usergroup
312 grant permission for given usergroup
313
313
314 :param user_group_id:
314 :param user_group_id:
315 """
315 """
316 user_group_id = safe_int(user_group_id)
316 user_group_id = safe_int(user_group_id)
317 c.user_group = UserGroup.get_or_404(user_group_id)
317 c.user_group = UserGroup.get_or_404(user_group_id)
318 form = UserGroupPermsForm()().to_python(request.POST)
318 form = UserGroupPermsForm()().to_python(request.POST)
319
319
320 if not c.rhodecode_user.is_admin:
320 if not c.rhodecode_user.is_admin:
321 if self._revoke_perms_on_yourself(form):
321 if self._revoke_perms_on_yourself(form):
322 msg = _('Cannot change permission for yourself as admin')
322 msg = _('Cannot change permission for yourself as admin')
323 h.flash(msg, category='warning')
323 h.flash(msg, category='warning')
324 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
324 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
325
325
326 try:
326 try:
327 UserGroupModel().update_permissions(user_group_id,
327 UserGroupModel().update_permissions(user_group_id,
328 form['perm_additions'], form['perm_updates'], form['perm_deletions'])
328 form['perm_additions'], form['perm_updates'], form['perm_deletions'])
329 except RepoGroupAssignmentError:
329 except RepoGroupAssignmentError:
330 h.flash(_('Target group cannot be the same'), category='error')
330 h.flash(_('Target group cannot be the same'), category='error')
331 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
331 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
332 #TODO: implement this
332 #TODO: implement this
333 #action_logger(c.rhodecode_user, 'admin_changed_repo_permissions',
333 #action_logger(c.rhodecode_user, 'admin_changed_repo_permissions',
334 # repo_name, self.ip_addr, self.sa)
334 # repo_name, self.ip_addr, self.sa)
335 Session().commit()
335 Session().commit()
336 h.flash(_('User Group permissions updated'), category='success')
336 h.flash(_('User Group permissions updated'), category='success')
337 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
337 return redirect(url('edit_user_group_perms', user_group_id=user_group_id))
338
338
339 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
339 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
340 def edit_perms_summary(self, user_group_id):
340