##// END OF EJS Templates
repos: only flush permissions for owner on creation. The repo creation task flushes ALL and can be done async
super-admin -
r4869:dbc52491 default
parent child Browse files
Show More
@@ -1,249 +1,250 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2020 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 formencode
23 23 import formencode.htmlfill
24 24
25 25 from pyramid.httpexceptions import HTTPFound, HTTPForbidden
26 26
27 27 from pyramid.renderers import render
28 28 from pyramid.response import Response
29 29
30 30 from rhodecode import events
31 31 from rhodecode.apps._base import BaseAppView, DataGridAppView
32 32 from rhodecode.lib.celerylib.utils import get_task_id
33 33
34 34 from rhodecode.lib.auth import (
35 35 LoginRequired, CSRFRequired, NotAnonymous,
36 36 HasPermissionAny, HasRepoGroupPermissionAny)
37 37 from rhodecode.lib import helpers as h
38 38 from rhodecode.lib.utils import repo_name_slug
39 39 from rhodecode.lib.utils2 import safe_int, safe_unicode
40 40 from rhodecode.model.forms import RepoForm
41 41 from rhodecode.model.permission import PermissionModel
42 42 from rhodecode.model.repo import RepoModel
43 43 from rhodecode.model.scm import RepoList, RepoGroupList, ScmModel
44 44 from rhodecode.model.settings import SettingsModel
45 45 from rhodecode.model.db import (
46 46 in_filter_generator, or_, func, Session, Repository, RepoGroup, User)
47 47
48 48 log = logging.getLogger(__name__)
49 49
50 50
51 51 class AdminReposView(BaseAppView, DataGridAppView):
52 52
53 53 def load_default_context(self):
54 54 c = self._get_local_tmpl_context()
55 55 return c
56 56
57 57 def _load_form_data(self, c):
58 58 acl_groups = RepoGroupList(RepoGroup.query().all(),
59 59 perm_set=['group.write', 'group.admin'])
60 60 c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
61 61 c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups)
62 62 c.personal_repo_group = self._rhodecode_user.personal_repo_group
63 63
64 64 @LoginRequired()
65 65 @NotAnonymous()
66 66 # perms check inside
67 67 def repository_list(self):
68 68 c = self.load_default_context()
69 69 return self._get_template_context(c)
70 70
71 71 @LoginRequired()
72 72 @NotAnonymous()
73 73 # perms check inside
74 74 def repository_list_data(self):
75 75 self.load_default_context()
76 76 column_map = {
77 77 'name': 'repo_name',
78 78 'desc': 'description',
79 79 'last_change': 'updated_on',
80 80 'owner': 'user_username',
81 81 }
82 82 draw, start, limit = self._extract_chunk(self.request)
83 83 search_q, order_by, order_dir = self._extract_ordering(
84 84 self.request, column_map=column_map)
85 85
86 86 _perms = ['repository.admin']
87 87 allowed_ids = [-1] + self._rhodecode_user.repo_acl_ids_from_stack(_perms)
88 88
89 89 repos_data_total_count = Repository.query() \
90 90 .filter(or_(
91 91 # generate multiple IN to fix limitation problems
92 92 *in_filter_generator(Repository.repo_id, allowed_ids))
93 93 ) \
94 94 .count()
95 95
96 96 base_q = Session.query(
97 97 Repository.repo_id,
98 98 Repository.repo_name,
99 99 Repository.description,
100 100 Repository.repo_type,
101 101 Repository.repo_state,
102 102 Repository.private,
103 103 Repository.archived,
104 104 Repository.fork,
105 105 Repository.updated_on,
106 106 Repository._changeset_cache,
107 107 User,
108 108 ) \
109 109 .filter(or_(
110 110 # generate multiple IN to fix limitation problems
111 111 *in_filter_generator(Repository.repo_id, allowed_ids))
112 112 ) \
113 113 .join(User, User.user_id == Repository.user_id) \
114 114 .group_by(Repository, User)
115 115
116 116 if search_q:
117 117 like_expression = u'%{}%'.format(safe_unicode(search_q))
118 118 base_q = base_q.filter(or_(
119 119 Repository.repo_name.ilike(like_expression),
120 120 ))
121 121
122 122 repos_data_total_filtered_count = base_q.count()
123 123
124 124 sort_defined = False
125 125 if order_by == 'repo_name':
126 126 sort_col = func.lower(Repository.repo_name)
127 127 sort_defined = True
128 128 elif order_by == 'user_username':
129 129 sort_col = User.username
130 130 else:
131 131 sort_col = getattr(Repository, order_by, None)
132 132
133 133 if sort_defined or sort_col:
134 134 if order_dir == 'asc':
135 135 sort_col = sort_col.asc()
136 136 else:
137 137 sort_col = sort_col.desc()
138 138
139 139 base_q = base_q.order_by(sort_col)
140 140 base_q = base_q.offset(start).limit(limit)
141 141
142 142 repos_list = base_q.all()
143 143
144 144 repos_data = RepoModel().get_repos_as_dict(
145 145 repo_list=repos_list, admin=True, super_user_actions=True)
146 146
147 147 data = ({
148 148 'draw': draw,
149 149 'data': repos_data,
150 150 'recordsTotal': repos_data_total_count,
151 151 'recordsFiltered': repos_data_total_filtered_count,
152 152 })
153 153 return data
154 154
155 155 @LoginRequired()
156 156 @NotAnonymous()
157 157 # perms check inside
158 158 def repository_new(self):
159 159 c = self.load_default_context()
160 160
161 161 new_repo = self.request.GET.get('repo', '')
162 162 parent_group_id = safe_int(self.request.GET.get('parent_group'))
163 163 _gr = RepoGroup.get(parent_group_id)
164 164
165 165 if not HasPermissionAny('hg.admin', 'hg.create.repository')():
166 166 # you're not super admin nor have global create permissions,
167 167 # but maybe you have at least write permission to a parent group ?
168 168
169 169 gr_name = _gr.group_name if _gr else None
170 170 # create repositories with write permission on group is set to true
171 171 create_on_write = HasPermissionAny('hg.create.write_on_repogroup.true')()
172 172 group_admin = HasRepoGroupPermissionAny('group.admin')(group_name=gr_name)
173 173 group_write = HasRepoGroupPermissionAny('group.write')(group_name=gr_name)
174 174 if not (group_admin or (group_write and create_on_write)):
175 175 raise HTTPForbidden()
176 176
177 177 self._load_form_data(c)
178 178 c.new_repo = repo_name_slug(new_repo)
179 179
180 180 # apply the defaults from defaults page
181 181 defaults = SettingsModel().get_default_repo_settings(strip_prefix=True)
182 182 # set checkbox to autochecked
183 183 defaults['repo_copy_permissions'] = True
184 184
185 185 parent_group_choice = '-1'
186 186 if not self._rhodecode_user.is_admin and self._rhodecode_user.personal_repo_group:
187 187 parent_group_choice = self._rhodecode_user.personal_repo_group
188 188
189 189 if parent_group_id and _gr:
190 190 if parent_group_id in [x[0] for x in c.repo_groups]:
191 191 parent_group_choice = safe_unicode(parent_group_id)
192 192
193 193 defaults.update({'repo_group': parent_group_choice})
194 194
195 195 data = render('rhodecode:templates/admin/repos/repo_add.mako',
196 196 self._get_template_context(c), self.request)
197 197 html = formencode.htmlfill.render(
198 198 data,
199 199 defaults=defaults,
200 200 encoding="UTF-8",
201 201 force_defaults=False
202 202 )
203 203 return Response(html)
204 204
205 205 @LoginRequired()
206 206 @NotAnonymous()
207 207 @CSRFRequired()
208 208 # perms check inside
209 209 def repository_create(self):
210 210 c = self.load_default_context()
211 211
212 212 form_result = {}
213 213 self._load_form_data(c)
214 214
215 215 try:
216 216 # CanWriteToGroup validators checks permissions of this POST
217 217 form = RepoForm(
218 218 self.request.translate, repo_groups=c.repo_groups_choices)()
219 219 form_result = form.to_python(dict(self.request.POST))
220 220 copy_permissions = form_result.get('repo_copy_permissions')
221 221 # create is done sometimes async on celery, db transaction
222 222 # management is handled there.
223 223 task = RepoModel().create(form_result, self._rhodecode_user.user_id)
224 224 task_id = get_task_id(task)
225 225 except formencode.Invalid as errors:
226 226 data = render('rhodecode:templates/admin/repos/repo_add.mako',
227 227 self._get_template_context(c), self.request)
228 228 html = formencode.htmlfill.render(
229 229 data,
230 230 defaults=errors.value,
231 231 errors=errors.error_dict or {},
232 232 prefix_error=False,
233 233 encoding="UTF-8",
234 234 force_defaults=False
235 235 )
236 236 return Response(html)
237 237
238 238 except Exception as e:
239 239 msg = self._log_creation_exception(e, form_result.get('repo_name'))
240 240 h.flash(msg, category='error')
241 241 raise HTTPFound(h.route_path('home'))
242 242
243 243 repo_name = form_result.get('repo_name_full')
244 244
245 PermissionModel().trigger_permission_flush()
245 affected_user_ids = [self._rhodecode_user.user_id]
246 PermissionModel().trigger_permission_flush(affected_user_ids)
246 247
247 248 raise HTTPFound(
248 249 h.route_path('repo_creating', repo_name=repo_name,
249 250 _query=dict(task_id=task_id)))
General Comments 0
You need to be logged in to leave comments. Login now