##// END OF EJS Templates
caches: flush permission caches when editing affected objects so we can reach them right after changes.
marcink -
r2876:3939ff15 default
parent child Browse files
Show More
@@ -1,183 +1,189 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2011-2018 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 import logging
22 22 import deform
23 23
24 24 from pyramid.view import view_config
25 25 from pyramid.httpexceptions import HTTPFound
26 26
27 from rhodecode import events
27 28 from rhodecode.apps._base import RepoGroupAppView
28 29 from rhodecode.forms import RcForm
29 30 from rhodecode.lib import helpers as h
30 31 from rhodecode.lib import audit_logger
31 32 from rhodecode.lib.auth import (
32 33 LoginRequired, HasPermissionAll,
33 34 HasRepoGroupPermissionAny, HasRepoGroupPermissionAnyDecorator, CSRFRequired)
34 from rhodecode.model.db import Session, RepoGroup
35 from rhodecode.model.db import Session, RepoGroup, User
35 36 from rhodecode.model.scm import RepoGroupList
36 37 from rhodecode.model.repo_group import RepoGroupModel
37 38 from rhodecode.model.validation_schema.schemas import repo_group_schema
38 39
39 40 log = logging.getLogger(__name__)
40 41
41 42
42 43 class RepoGroupSettingsView(RepoGroupAppView):
43 44 def load_default_context(self):
44 45 c = self._get_local_tmpl_context()
45 46 c.repo_group = self.db_repo_group
46 47 no_parrent = not c.repo_group.parent_group
47 48 can_create_in_root = self._can_create_repo_group()
48 49
49 50 show_root_location = False
50 51 if no_parrent or can_create_in_root:
51 52 # we're global admin, we're ok and we can create TOP level groups
52 53 # or in case this group is already at top-level we also allow
53 54 # creation in root
54 55 show_root_location = True
55 56
56 57 acl_groups = RepoGroupList(
57 58 RepoGroup.query().all(),
58 59 perm_set=['group.admin'])
59 60 c.repo_groups = RepoGroup.groups_choices(
60 61 groups=acl_groups,
61 62 show_empty_group=show_root_location)
62 63 # filter out current repo group
63 64 exclude_group_ids = [c.repo_group.group_id]
64 65 c.repo_groups = filter(lambda x: x[0] not in exclude_group_ids,
65 66 c.repo_groups)
66 67 c.repo_groups_choices = map(lambda k: k[0], c.repo_groups)
67 68
68 69 parent_group = c.repo_group.parent_group
69 70
70 71 add_parent_group = (parent_group and (
71 72 parent_group.group_id not in c.repo_groups_choices))
72 73 if add_parent_group:
73 74 c.repo_groups_choices.append(parent_group.group_id)
74 75 c.repo_groups.append(RepoGroup._generate_choice(parent_group))
75
76
77 76 return c
78 77
79 78 def _can_create_repo_group(self, parent_group_id=None):
80 79 is_admin = HasPermissionAll('hg.admin')('group create controller')
81 80 create_repo_group = HasPermissionAll(
82 81 'hg.repogroup.create.true')('group create controller')
83 82 if is_admin or (create_repo_group and not parent_group_id):
84 83 # we're global admin, or we have global repo group create
85 84 # permission
86 85 # we're ok and we can create TOP level groups
87 86 return True
88 87 elif parent_group_id:
89 88 # we check the permission if we can write to parent group
90 89 group = RepoGroup.get(parent_group_id)
91 90 group_name = group.group_name if group else None
92 91 if HasRepoGroupPermissionAny('group.admin')(
93 92 group_name, 'check if user is an admin of group'):
94 93 # we're an admin of passed in group, we're ok.
95 94 return True
96 95 else:
97 96 return False
98 97 return False
99 98
100 99 def _get_schema(self, c, old_values=None):
101 100 return repo_group_schema.RepoGroupSettingsSchema().bind(
102 101 repo_group_repo_group_options=c.repo_groups_choices,
103 102 repo_group_repo_group_items=c.repo_groups,
104 103
105 104 # user caller
106 105 user=self._rhodecode_user,
107 106 old_values=old_values
108 107 )
109 108
110 109 @LoginRequired()
111 110 @HasRepoGroupPermissionAnyDecorator('group.admin')
112 111 @view_config(
113 112 route_name='edit_repo_group', request_method='GET',
114 113 renderer='rhodecode:templates/admin/repo_groups/repo_group_edit.mako')
115 114 def edit_settings(self):
116 115 c = self.load_default_context()
117 116 c.active = 'settings'
118 117
119 118 defaults = RepoGroupModel()._get_defaults(self.db_repo_group_name)
120 119 defaults['repo_group_owner'] = defaults['user']
121 120
122 121 schema = self._get_schema(c)
123 122 c.form = RcForm(schema, appstruct=defaults)
124 123 return self._get_template_context(c)
125 124
126 125 @LoginRequired()
127 126 @HasRepoGroupPermissionAnyDecorator('group.admin')
128 127 @CSRFRequired()
129 128 @view_config(
130 129 route_name='edit_repo_group', request_method='POST',
131 130 renderer='rhodecode:templates/admin/repo_groups/repo_group_edit.mako')
132 131 def edit_settings_update(self):
133 132 _ = self.request.translate
134 133 c = self.load_default_context()
135 134 c.active = 'settings'
136 135
137 136 old_repo_group_name = self.db_repo_group_name
138 137 new_repo_group_name = old_repo_group_name
139 138
140 139 old_values = RepoGroupModel()._get_defaults(self.db_repo_group_name)
141 140 schema = self._get_schema(c, old_values=old_values)
142 141
143 142 c.form = RcForm(schema)
144 143 pstruct = self.request.POST.items()
145 144
146 145 try:
147 146 schema_data = c.form.validate(pstruct)
148 147 except deform.ValidationFailure as err_form:
149 148 return self._get_template_context(c)
150 149
151 150 # data is now VALID, proceed with updates
152 151 # save validated data back into the updates dict
153 152 validated_updates = dict(
154 153 group_name=schema_data['repo_group']['repo_group_name_without_group'],
155 154 group_parent_id=schema_data['repo_group']['repo_group_id'],
156 155 user=schema_data['repo_group_owner'],
157 156 group_description=schema_data['repo_group_description'],
158 157 enable_locking=schema_data['repo_group_enable_locking'],
159 158 )
160 159
161 160 try:
162 161 RepoGroupModel().update(self.db_repo_group, validated_updates)
163 162
164 163 audit_logger.store_web(
165 164 'repo_group.edit', action_data={'old_data': old_values},
166 165 user=c.rhodecode_user)
167 166
168 167 Session().commit()
169 168
170 169 # use the new full name for redirect once we know we updated
171 170 # the name on filesystem and in DB
172 171 new_repo_group_name = schema_data['repo_group']['repo_group_name_with_group']
173 172
174 173 h.flash(_('Repository Group `{}` updated successfully').format(
175 174 old_repo_group_name), category='success')
176 175
177 176 except Exception:
178 177 log.exception("Exception during update or repository group")
179 178 h.flash(_('Error occurred during update of repository group %s')
180 179 % old_repo_group_name, category='error')
181 180
181 name_changed = old_repo_group_name != new_repo_group_name
182 if name_changed:
183 owner = User.get_by_username(schema_data['repo_group_owner'])
184 owner_id = owner.user_id if owner else self._rhodecode_user.user_id
185 events.trigger(events.UserPermissionsChange([
186 self._rhodecode_user.user_id, owner_id]))
187
182 188 raise HTTPFound(
183 189 h.route_path('edit_repo_group', repo_group_name=new_repo_group_name))
@@ -1,256 +1,262 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2011-2018 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 import logging
22 22
23 23 import deform
24 24 from pyramid.httpexceptions import HTTPFound
25 25 from pyramid.view import view_config
26 26
27 from rhodecode import events
27 28 from rhodecode.apps._base import RepoAppView
28 29 from rhodecode.forms import RcForm
29 30 from rhodecode.lib import helpers as h
30 31 from rhodecode.lib import audit_logger
31 32 from rhodecode.lib.auth import (
32 33 LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired)
33 from rhodecode.model.db import RepositoryField, RepoGroup, Repository
34 from rhodecode.model.db import RepositoryField, RepoGroup, Repository, User
34 35 from rhodecode.model.meta import Session
35 36 from rhodecode.model.repo import RepoModel
36 37 from rhodecode.model.scm import RepoGroupList, ScmModel
37 38 from rhodecode.model.validation_schema.schemas import repo_schema
38 39
39 40 log = logging.getLogger(__name__)
40 41
41 42
42 43 class RepoSettingsView(RepoAppView):
43 44
44 45 def load_default_context(self):
45 46 c = self._get_local_tmpl_context()
46 47
47 48 acl_groups = RepoGroupList(
48 49 RepoGroup.query().all(),
49 50 perm_set=['group.write', 'group.admin'])
50 51 c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
51 52 c.repo_groups_choices = map(lambda k: k[0], c.repo_groups)
52 53
53 54 # in case someone no longer have a group.write access to a repository
54 55 # pre fill the list with this entry, we don't care if this is the same
55 56 # but it will allow saving repo data properly.
56 57 repo_group = self.db_repo.group
57 58 if repo_group and repo_group.group_id not in c.repo_groups_choices:
58 59 c.repo_groups_choices.append(repo_group.group_id)
59 60 c.repo_groups.append(RepoGroup._generate_choice(repo_group))
60 61
61 62 if c.repository_requirements_missing or self.rhodecode_vcs_repo is None:
62 63 # we might be in missing requirement state, so we load things
63 64 # without touching scm_instance()
64 65 c.landing_revs_choices, c.landing_revs = \
65 66 ScmModel().get_repo_landing_revs(self.request.translate)
66 67 else:
67 68 c.landing_revs_choices, c.landing_revs = \
68 69 ScmModel().get_repo_landing_revs(
69 70 self.request.translate, self.db_repo)
70 71
71 72 c.personal_repo_group = c.auth_user.personal_repo_group
72 73 c.repo_fields = RepositoryField.query()\
73 74 .filter(RepositoryField.repository == self.db_repo).all()
74
75
76 75 return c
77 76
78 77 def _get_schema(self, c, old_values=None):
79 78 return repo_schema.RepoSettingsSchema().bind(
80 79 repo_type=self.db_repo.repo_type,
81 80 repo_type_options=[self.db_repo.repo_type],
82 81 repo_ref_options=c.landing_revs_choices,
83 82 repo_ref_items=c.landing_revs,
84 83 repo_repo_group_options=c.repo_groups_choices,
85 84 repo_repo_group_items=c.repo_groups,
86 85 # user caller
87 86 user=self._rhodecode_user,
88 87 old_values=old_values
89 88 )
90 89
91 90 @LoginRequired()
92 91 @HasRepoPermissionAnyDecorator('repository.admin')
93 92 @view_config(
94 93 route_name='edit_repo', request_method='GET',
95 94 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
96 95 def edit_settings(self):
97 96 c = self.load_default_context()
98 97 c.active = 'settings'
99 98
100 99 defaults = RepoModel()._get_defaults(self.db_repo_name)
101 100 defaults['repo_owner'] = defaults['user']
102 101 defaults['repo_landing_commit_ref'] = defaults['repo_landing_rev']
103 102
104 103 schema = self._get_schema(c)
105 104 c.form = RcForm(schema, appstruct=defaults)
106 105 return self._get_template_context(c)
107 106
108 107 @LoginRequired()
109 108 @HasRepoPermissionAnyDecorator('repository.admin')
110 109 @CSRFRequired()
111 110 @view_config(
112 111 route_name='edit_repo', request_method='POST',
113 112 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
114 113 def edit_settings_update(self):
115 114 _ = self.request.translate
116 115 c = self.load_default_context()
117 116 c.active = 'settings'
118 117 old_repo_name = self.db_repo_name
119 118
120 119 old_values = self.db_repo.get_api_data()
121 120 schema = self._get_schema(c, old_values=old_values)
122 121
123 122 c.form = RcForm(schema)
124 123 pstruct = self.request.POST.items()
125 124 pstruct.append(('repo_type', self.db_repo.repo_type))
126 125 try:
127 126 schema_data = c.form.validate(pstruct)
128 127 except deform.ValidationFailure as err_form:
129 128 return self._get_template_context(c)
130 129
131 130 # data is now VALID, proceed with updates
132 131 # save validated data back into the updates dict
133 132 validated_updates = dict(
134 133 repo_name=schema_data['repo_group']['repo_name_without_group'],
135 134 repo_group=schema_data['repo_group']['repo_group_id'],
136 135
137 136 user=schema_data['repo_owner'],
138 137 repo_description=schema_data['repo_description'],
139 138 repo_private=schema_data['repo_private'],
140 139 clone_uri=schema_data['repo_clone_uri'],
141 140 push_uri=schema_data['repo_push_uri'],
142 141 repo_landing_rev=schema_data['repo_landing_commit_ref'],
143 142 repo_enable_statistics=schema_data['repo_enable_statistics'],
144 143 repo_enable_locking=schema_data['repo_enable_locking'],
145 144 repo_enable_downloads=schema_data['repo_enable_downloads'],
146 145 )
147 146 # detect if SYNC URI changed, if we get OLD means we keep old values
148 147 if schema_data['repo_clone_uri_change'] == 'OLD':
149 148 validated_updates['clone_uri'] = self.db_repo.clone_uri
150 149
151 150 if schema_data['repo_push_uri_change'] == 'OLD':
152 151 validated_updates['push_uri'] = self.db_repo.push_uri
153 152
154 153 # use the new full name for redirect
155 154 new_repo_name = schema_data['repo_group']['repo_name_with_group']
156 155
157 156 # save extra fields into our validated data
158 157 for key, value in pstruct:
159 158 if key.startswith(RepositoryField.PREFIX):
160 159 validated_updates[key] = value
161 160
162 161 try:
163 162 RepoModel().update(self.db_repo, **validated_updates)
164 163 ScmModel().mark_for_invalidation(new_repo_name)
165 164
166 165 audit_logger.store_web(
167 166 'repo.edit', action_data={'old_data': old_values},
168 167 user=self._rhodecode_user, repo=self.db_repo)
169 168
170 169 Session().commit()
171 170
172 171 h.flash(_('Repository `{}` updated successfully').format(
173 172 old_repo_name), category='success')
174 173 except Exception:
175 174 log.exception("Exception during update of repository")
176 175 h.flash(_('Error occurred during update of repository {}').format(
177 176 old_repo_name), category='error')
178 177
178 name_changed = old_repo_name != new_repo_name
179 if name_changed:
180 owner = User.get_by_username(schema_data['repo_owner'])
181 owner_id = owner.user_id if owner else self._rhodecode_user.user_id
182 events.trigger(events.UserPermissionsChange([
183 self._rhodecode_user.user_id, owner_id]))
184
179 185 raise HTTPFound(
180 186 h.route_path('edit_repo', repo_name=new_repo_name))
181 187
182 188 @LoginRequired()
183 189 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
184 190 @view_config(
185 191 route_name='repo_edit_toggle_locking', request_method='GET',
186 192 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
187 193 def toggle_locking(self):
188 194 """
189 195 Toggle locking of repository by simple GET call to url
190 196 """
191 197 _ = self.request.translate
192 198 repo = self.db_repo
193 199
194 200 try:
195 201 if repo.enable_locking:
196 202 if repo.locked[0]:
197 203 Repository.unlock(repo)
198 204 action = _('Unlocked')
199 205 else:
200 206 Repository.lock(
201 207 repo, self._rhodecode_user.user_id,
202 208 lock_reason=Repository.LOCK_WEB)
203 209 action = _('Locked')
204 210
205 211 h.flash(_('Repository has been %s') % action,
206 212 category='success')
207 213 except Exception:
208 214 log.exception("Exception during unlocking")
209 215 h.flash(_('An error occurred during unlocking'),
210 216 category='error')
211 217 raise HTTPFound(
212 218 h.route_path('repo_summary', repo_name=self.db_repo_name))
213 219
214 220 @LoginRequired()
215 221 @HasRepoPermissionAnyDecorator('repository.admin')
216 222 @view_config(
217 223 route_name='edit_repo_statistics', request_method='GET',
218 224 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
219 225 def edit_statistics_form(self):
220 226 c = self.load_default_context()
221 227
222 228 if self.db_repo.stats:
223 229 # this is on what revision we ended up so we add +1 for count
224 230 last_rev = self.db_repo.stats.stat_on_revision + 1
225 231 else:
226 232 last_rev = 0
227 233
228 234 c.active = 'statistics'
229 235 c.stats_revision = last_rev
230 236 c.repo_last_rev = self.rhodecode_vcs_repo.count()
231 237
232 238 if last_rev == 0 or c.repo_last_rev == 0:
233 239 c.stats_percentage = 0
234 240 else:
235 241 c.stats_percentage = '%.2f' % (
236 242 (float((last_rev)) / c.repo_last_rev) * 100)
237 243 return self._get_template_context(c)
238 244
239 245 @LoginRequired()
240 246 @HasRepoPermissionAnyDecorator('repository.admin')
241 247 @CSRFRequired()
242 248 @view_config(
243 249 route_name='edit_repo_statistics_reset', request_method='POST',
244 250 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
245 251 def repo_statistics_reset(self):
246 252 _ = self.request.translate
247 253
248 254 try:
249 255 RepoModel().delete_stats(self.db_repo_name)
250 256 Session().commit()
251 257 except Exception:
252 258 log.exception('Edit statistics failure')
253 259 h.flash(_('An error occurred during deletion of repository stats'),
254 260 category='error')
255 261 raise HTTPFound(
256 262 h.route_path('edit_repo_statistics', repo_name=self.db_repo_name))
@@ -1,534 +1,545 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2018 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 import logging
22 22
23 23 import peppercorn
24 24 import formencode
25 25 import formencode.htmlfill
26 26 from pyramid.httpexceptions import HTTPFound
27 27 from pyramid.view import view_config
28 28 from pyramid.response import Response
29 29 from pyramid.renderers import render
30 30
31 31 from rhodecode import events
32 32 from rhodecode.lib.exceptions import (
33 33 RepoGroupAssignmentError, UserGroupAssignedException)
34 34 from rhodecode.model.forms import (
35 35 UserGroupPermsForm, UserGroupForm, UserIndividualPermissionsForm,
36 36 UserPermissionsForm)
37 37 from rhodecode.model.permission import PermissionModel
38 38
39 39 from rhodecode.apps._base import UserGroupAppView
40 40 from rhodecode.lib.auth import (
41 41 LoginRequired, HasUserGroupPermissionAnyDecorator, CSRFRequired)
42 42 from rhodecode.lib import helpers as h, audit_logger
43 43 from rhodecode.lib.utils2 import str2bool
44 44 from rhodecode.model.db import User
45 45 from rhodecode.model.meta import Session
46 46 from rhodecode.model.user_group import UserGroupModel
47 47
48 48 log = logging.getLogger(__name__)
49 49
50 50
51 51 class UserGroupsView(UserGroupAppView):
52 52
53 53 def load_default_context(self):
54 54 c = self._get_local_tmpl_context()
55 55
56 56 PermissionModel().set_global_permission_choices(
57 57 c, gettext_translator=self.request.translate)
58 58
59 59 return c
60 60
61 61 @LoginRequired()
62 62 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
63 63 @view_config(
64 64 route_name='user_group_members_data', request_method='GET',
65 65 renderer='json_ext', xhr=True)
66 66 def user_group_members(self):
67 67 """
68 68 Return members of given user group
69 69 """
70 70 self.load_default_context()
71 71 user_group = self.db_user_group
72 72 group_members_obj = sorted((x.user for x in user_group.members),
73 73 key=lambda u: u.username.lower())
74 74
75 75 group_members = [
76 76 {
77 77 'id': user.user_id,
78 78 'first_name': user.first_name,
79 79 'last_name': user.last_name,
80 80 'username': user.username,
81 81 'icon_link': h.gravatar_url(user.email, 30),
82 82 'value_display': h.person(user.email),
83 83 'value': user.username,
84 84 'value_type': 'user',
85 85 'active': user.active,
86 86 }
87 87 for user in group_members_obj
88 88 ]
89 89
90 90 return {
91 91 'members': group_members
92 92 }
93 93
94 94 @LoginRequired()
95 95 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
96 96 @view_config(
97 97 route_name='edit_user_group_perms_summary', request_method='GET',
98 98 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
99 99 def user_group_perms_summary(self):
100 100 c = self.load_default_context()
101 101 c.user_group = self.db_user_group
102 102 c.active = 'perms_summary'
103 103 c.permissions = UserGroupModel().get_perms_summary(
104 104 c.user_group.users_group_id)
105 105 return self._get_template_context(c)
106 106
107 107 @LoginRequired()
108 108 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
109 109 @view_config(
110 110 route_name='edit_user_group_perms_summary_json', request_method='GET',
111 111 renderer='json_ext')
112 112 def user_group_perms_summary_json(self):
113 113 self.load_default_context()
114 114 user_group = self.db_user_group
115 115 return UserGroupModel().get_perms_summary(user_group.users_group_id)
116 116
117 117 def _revoke_perms_on_yourself(self, form_result):
118 118 _updates = filter(lambda u: self._rhodecode_user.user_id == int(u[0]),
119 119 form_result['perm_updates'])
120 120 _additions = filter(lambda u: self._rhodecode_user.user_id == int(u[0]),
121 121 form_result['perm_additions'])
122 122 _deletions = filter(lambda u: self._rhodecode_user.user_id == int(u[0]),
123 123 form_result['perm_deletions'])
124 124 admin_perm = 'usergroup.admin'
125 125 if _updates and _updates[0][1] != admin_perm or \
126 126 _additions and _additions[0][1] != admin_perm or \
127 127 _deletions and _deletions[0][1] != admin_perm:
128 128 return True
129 129 return False
130 130
131 131 @LoginRequired()
132 132 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
133 133 @CSRFRequired()
134 134 @view_config(
135 135 route_name='user_groups_update', request_method='POST',
136 136 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
137 137 def user_group_update(self):
138 138 _ = self.request.translate
139 139
140 140 user_group = self.db_user_group
141 141 user_group_id = user_group.users_group_id
142 142
143 old_user_group_name = self.db_user_group_name
144 new_user_group_name = old_user_group_name
145
143 146 c = self.load_default_context()
144 147 c.user_group = user_group
145 148 c.group_members_obj = [x.user for x in c.user_group.members]
146 149 c.group_members_obj.sort(key=lambda u: u.username.lower())
147 150 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
148 151 c.active = 'settings'
149 152
150 153 users_group_form = UserGroupForm(
151 154 self.request.translate, edit=True,
152 155 old_data=c.user_group.get_dict(), allow_disabled=True)()
153 156
154 157 old_values = c.user_group.get_api_data()
155 user_group_name = self.request.POST.get('users_group_name')
158
156 159 try:
157 160 form_result = users_group_form.to_python(self.request.POST)
158 161 pstruct = peppercorn.parse(self.request.POST.items())
159 162 form_result['users_group_members'] = pstruct['user_group_members']
160 163
161 164 user_group, added_members, removed_members = \
162 165 UserGroupModel().update(c.user_group, form_result)
163 updated_user_group = form_result['users_group_name']
166 new_user_group_name = form_result['users_group_name']
164 167
165 168 for user_id in added_members:
166 169 user = User.get(user_id)
167 170 user_data = user.get_api_data()
168 171 audit_logger.store_web(
169 172 'user_group.edit.member.add',
170 173 action_data={'user': user_data, 'old_data': old_values},
171 174 user=self._rhodecode_user)
172 175
173 176 for user_id in removed_members:
174 177 user = User.get(user_id)
175 178 user_data = user.get_api_data()
176 179 audit_logger.store_web(
177 180 'user_group.edit.member.delete',
178 181 action_data={'user': user_data, 'old_data': old_values},
179 182 user=self._rhodecode_user)
180 183
181 184 audit_logger.store_web(
182 185 'user_group.edit', action_data={'old_data': old_values},
183 186 user=self._rhodecode_user)
184 187
185 h.flash(_('Updated user group %s') % updated_user_group,
188 h.flash(_('Updated user group %s') % new_user_group_name,
186 189 category='success')
187 190
188 191 affected_user_ids = []
189 192 for user_id in added_members + removed_members:
190 193 affected_user_ids.append(user_id)
194
195 name_changed = old_user_group_name != new_user_group_name
196 if name_changed:
197 owner = User.get_by_username(form_result['user'])
198 owner_id = owner.user_id if owner else self._rhodecode_user.user_id
199 affected_user_ids.append(self._rhodecode_user.user_id)
200 affected_user_ids.append(owner_id)
201
191 202 events.trigger(events.UserPermissionsChange(affected_user_ids))
192 203
193 204 Session().commit()
194 205 except formencode.Invalid as errors:
195 206 defaults = errors.value
196 207 e = errors.error_dict or {}
197 208
198 209 data = render(
199 210 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
200 211 self._get_template_context(c), self.request)
201 212 html = formencode.htmlfill.render(
202 213 data,
203 214 defaults=defaults,
204 215 errors=e,
205 216 prefix_error=False,
206 217 encoding="UTF-8",
207 218 force_defaults=False
208 219 )
209 220 return Response(html)
210 221
211 222 except Exception:
212 223 log.exception("Exception during update of user group")
213 224 h.flash(_('Error occurred during update of user group %s')
214 % user_group_name, category='error')
225 % new_user_group_name, category='error')
215 226
216 227 raise HTTPFound(
217 228 h.route_path('edit_user_group', user_group_id=user_group_id))
218 229
219 230 @LoginRequired()
220 231 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
221 232 @CSRFRequired()
222 233 @view_config(
223 234 route_name='user_groups_delete', request_method='POST',
224 235 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
225 236 def user_group_delete(self):
226 237 _ = self.request.translate
227 238 user_group = self.db_user_group
228 239
229 240 self.load_default_context()
230 241 force = str2bool(self.request.POST.get('force'))
231 242
232 243 old_values = user_group.get_api_data()
233 244 try:
234 245 UserGroupModel().delete(user_group, force=force)
235 246 audit_logger.store_web(
236 247 'user.delete', action_data={'old_data': old_values},
237 248 user=self._rhodecode_user)
238 249 Session().commit()
239 250 h.flash(_('Successfully deleted user group'), category='success')
240 251 except UserGroupAssignedException as e:
241 252 h.flash(str(e), category='error')
242 253 except Exception:
243 254 log.exception("Exception during deletion of user group")
244 255 h.flash(_('An error occurred during deletion of user group'),
245 256 category='error')
246 257 raise HTTPFound(h.route_path('user_groups'))
247 258
248 259 @LoginRequired()
249 260 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
250 261 @view_config(
251 262 route_name='edit_user_group', request_method='GET',
252 263 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
253 264 def user_group_edit(self):
254 265 user_group = self.db_user_group
255 266
256 267 c = self.load_default_context()
257 268 c.user_group = user_group
258 269 c.group_members_obj = [x.user for x in c.user_group.members]
259 270 c.group_members_obj.sort(key=lambda u: u.username.lower())
260 271 c.group_members = [(x.user_id, x.username) for x in c.group_members_obj]
261 272
262 273 c.active = 'settings'
263 274
264 275 defaults = user_group.get_dict()
265 276 # fill owner
266 277 if user_group.user:
267 278 defaults.update({'user': user_group.user.username})
268 279 else:
269 280 replacement_user = User.get_first_super_admin().username
270 281 defaults.update({'user': replacement_user})
271 282
272 283 data = render(
273 284 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
274 285 self._get_template_context(c), self.request)
275 286 html = formencode.htmlfill.render(
276 287 data,
277 288 defaults=defaults,
278 289 encoding="UTF-8",
279 290 force_defaults=False
280 291 )
281 292 return Response(html)
282 293
283 294 @LoginRequired()
284 295 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
285 296 @view_config(
286 297 route_name='edit_user_group_perms', request_method='GET',
287 298 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
288 299 def user_group_edit_perms(self):
289 300 user_group = self.db_user_group
290 301 c = self.load_default_context()
291 302 c.user_group = user_group
292 303 c.active = 'perms'
293 304
294 305 defaults = {}
295 306 # fill user group users
296 307 for p in c.user_group.user_user_group_to_perm:
297 308 defaults.update({'u_perm_%s' % p.user.user_id:
298 309 p.permission.permission_name})
299 310
300 311 for p in c.user_group.user_group_user_group_to_perm:
301 312 defaults.update({'g_perm_%s' % p.user_group.users_group_id:
302 313 p.permission.permission_name})
303 314
304 315 data = render(
305 316 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
306 317 self._get_template_context(c), self.request)
307 318 html = formencode.htmlfill.render(
308 319 data,
309 320 defaults=defaults,
310 321 encoding="UTF-8",
311 322 force_defaults=False
312 323 )
313 324 return Response(html)
314 325
315 326 @LoginRequired()
316 327 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
317 328 @CSRFRequired()
318 329 @view_config(
319 330 route_name='edit_user_group_perms_update', request_method='POST',
320 331 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
321 332 def user_group_update_perms(self):
322 333 """
323 334 grant permission for given user group
324 335 """
325 336 _ = self.request.translate
326 337
327 338 user_group = self.db_user_group
328 339 user_group_id = user_group.users_group_id
329 340 c = self.load_default_context()
330 341 c.user_group = user_group
331 342 form = UserGroupPermsForm(self.request.translate)().to_python(self.request.POST)
332 343
333 344 if not self._rhodecode_user.is_admin:
334 345 if self._revoke_perms_on_yourself(form):
335 346 msg = _('Cannot change permission for yourself as admin')
336 347 h.flash(msg, category='warning')
337 348 raise HTTPFound(
338 349 h.route_path('edit_user_group_perms',
339 350 user_group_id=user_group_id))
340 351
341 352 try:
342 353 changes = UserGroupModel().update_permissions(
343 354 user_group,
344 355 form['perm_additions'], form['perm_updates'],
345 356 form['perm_deletions'])
346 357
347 358 except RepoGroupAssignmentError:
348 359 h.flash(_('Target group cannot be the same'), category='error')
349 360 raise HTTPFound(
350 361 h.route_path('edit_user_group_perms',
351 362 user_group_id=user_group_id))
352 363
353 364 action_data = {
354 365 'added': changes['added'],
355 366 'updated': changes['updated'],
356 367 'deleted': changes['deleted'],
357 368 }
358 369 audit_logger.store_web(
359 370 'user_group.edit.permissions', action_data=action_data,
360 371 user=self._rhodecode_user)
361 372
362 373 Session().commit()
363 374 h.flash(_('User Group permissions updated'), category='success')
364 375
365 376 affected_user_ids = []
366 377 for change in changes['added'] + changes['updated'] + changes['deleted']:
367 378 if change['type'] == 'user':
368 379 affected_user_ids.append(change['id'])
369 380
370 381 events.trigger(events.UserPermissionsChange(affected_user_ids))
371 382
372 383 raise HTTPFound(
373 384 h.route_path('edit_user_group_perms', user_group_id=user_group_id))
374 385
375 386 @LoginRequired()
376 387 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
377 388 @view_config(
378 389 route_name='edit_user_group_global_perms', request_method='GET',
379 390 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
380 391 def user_group_global_perms_edit(self):
381 392 user_group = self.db_user_group
382 393 c = self.load_default_context()
383 394 c.user_group = user_group
384 395 c.active = 'global_perms'
385 396
386 397 c.default_user = User.get_default_user()
387 398 defaults = c.user_group.get_dict()
388 399 defaults.update(c.default_user.get_default_perms(suffix='_inherited'))
389 400 defaults.update(c.user_group.get_default_perms())
390 401
391 402 data = render(
392 403 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
393 404 self._get_template_context(c), self.request)
394 405 html = formencode.htmlfill.render(
395 406 data,
396 407 defaults=defaults,
397 408 encoding="UTF-8",
398 409 force_defaults=False
399 410 )
400 411 return Response(html)
401 412
402 413 @LoginRequired()
403 414 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
404 415 @CSRFRequired()
405 416 @view_config(
406 417 route_name='edit_user_group_global_perms_update', request_method='POST',
407 418 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
408 419 def user_group_global_perms_update(self):
409 420 _ = self.request.translate
410 421 user_group = self.db_user_group
411 422 user_group_id = self.db_user_group.users_group_id
412 423
413 424 c = self.load_default_context()
414 425 c.user_group = user_group
415 426 c.active = 'global_perms'
416 427
417 428 try:
418 429 # first stage that verifies the checkbox
419 430 _form = UserIndividualPermissionsForm(self.request.translate)
420 431 form_result = _form.to_python(dict(self.request.POST))
421 432 inherit_perms = form_result['inherit_default_permissions']
422 433 user_group.inherit_default_permissions = inherit_perms
423 434 Session().add(user_group)
424 435
425 436 if not inherit_perms:
426 437 # only update the individual ones if we un check the flag
427 438 _form = UserPermissionsForm(
428 439 self.request.translate,
429 440 [x[0] for x in c.repo_create_choices],
430 441 [x[0] for x in c.repo_create_on_write_choices],
431 442 [x[0] for x in c.repo_group_create_choices],
432 443 [x[0] for x in c.user_group_create_choices],
433 444 [x[0] for x in c.fork_choices],
434 445 [x[0] for x in c.inherit_default_permission_choices])()
435 446
436 447 form_result = _form.to_python(dict(self.request.POST))
437 448 form_result.update(
438 449 {'perm_user_group_id': user_group.users_group_id})
439 450
440 451 PermissionModel().update_user_group_permissions(form_result)
441 452
442 453 Session().commit()
443 454 h.flash(_('User Group global permissions updated successfully'),
444 455 category='success')
445 456
446 457 except formencode.Invalid as errors:
447 458 defaults = errors.value
448 459
449 460 data = render(
450 461 'rhodecode:templates/admin/user_groups/user_group_edit.mako',
451 462 self._get_template_context(c), self.request)
452 463 html = formencode.htmlfill.render(
453 464 data,
454 465 defaults=defaults,
455 466 errors=errors.error_dict or {},
456 467 prefix_error=False,
457 468 encoding="UTF-8",
458 469 force_defaults=False
459 470 )
460 471 return Response(html)
461 472 except Exception:
462 473 log.exception("Exception during permissions saving")
463 474 h.flash(_('An error occurred during permissions saving'),
464 475 category='error')
465 476
466 477 raise HTTPFound(
467 478 h.route_path('edit_user_group_global_perms',
468 479 user_group_id=user_group_id))
469 480
470 481 @LoginRequired()
471 482 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
472 483 @view_config(
473 484 route_name='edit_user_group_advanced', request_method='GET',
474 485 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
475 486 def user_group_edit_advanced(self):
476 487 user_group = self.db_user_group
477 488
478 489 c = self.load_default_context()
479 490 c.user_group = user_group
480 491 c.active = 'advanced'
481 492 c.group_members_obj = sorted(
482 493 (x.user for x in c.user_group.members),
483 494 key=lambda u: u.username.lower())
484 495
485 496 c.group_to_repos = sorted(
486 497 (x.repository for x in c.user_group.users_group_repo_to_perm),
487 498 key=lambda u: u.repo_name.lower())
488 499
489 500 c.group_to_repo_groups = sorted(
490 501 (x.group for x in c.user_group.users_group_repo_group_to_perm),
491 502 key=lambda u: u.group_name.lower())
492 503
493 504 c.group_to_review_rules = sorted(
494 505 (x.users_group for x in c.user_group.user_group_review_rules),
495 506 key=lambda u: u.users_group_name.lower())
496 507
497 508 return self._get_template_context(c)
498 509
499 510 @LoginRequired()
500 511 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
501 512 @CSRFRequired()
502 513 @view_config(
503 514 route_name='edit_user_group_advanced_sync', request_method='POST',
504 515 renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako')
505 516 def user_group_edit_advanced_set_synchronization(self):
506 517 _ = self.request.translate
507 518 user_group = self.db_user_group
508 519 user_group_id = user_group.users_group_id
509 520
510 521 existing = user_group.group_data.get('extern_type')
511 522
512 523 if existing:
513 524 new_state = user_group.group_data
514 525 new_state['extern_type'] = None
515 526 else:
516 527 new_state = user_group.group_data
517 528 new_state['extern_type'] = 'manual'
518 529 new_state['extern_type_set_by'] = self._rhodecode_user.username
519 530
520 531 try:
521 532 user_group.group_data = new_state
522 533 Session().add(user_group)
523 534 Session().commit()
524 535
525 536 h.flash(_('User Group synchronization updated successfully'),
526 537 category='success')
527 538 except Exception:
528 539 log.exception("Exception during sync settings saving")
529 540 h.flash(_('An error occurred during synchronization update'),
530 541 category='error')
531 542
532 543 raise HTTPFound(
533 544 h.route_path('edit_user_group_advanced',
534 545 user_group_id=user_group_id))
General Comments 0
You need to be logged in to leave comments. Login now