##// END OF EJS Templates
create: fixed case for repo groups that didn't pre-fill the repo group from GET param....
marcink -
r4424:cbe581e5 default
parent child Browse files
Show More
@@ -1,360 +1,374 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 import datetime
21 21 import logging
22 22 import time
23 23
24 24 import formencode
25 25 import formencode.htmlfill
26 26
27 27 from pyramid.httpexceptions import HTTPFound, HTTPForbidden
28 28 from pyramid.view import view_config
29 29 from pyramid.renderers import render
30 30 from pyramid.response import Response
31 31
32 32 from rhodecode import events
33 33 from rhodecode.apps._base import BaseAppView, DataGridAppView
34 34
35 35 from rhodecode.lib.auth import (
36 36 LoginRequired, CSRFRequired, NotAnonymous,
37 37 HasPermissionAny, HasRepoGroupPermissionAny)
38 38 from rhodecode.lib import helpers as h, audit_logger
39 39 from rhodecode.lib.utils2 import safe_int, safe_unicode, datetime_to_time
40 40 from rhodecode.model.forms import RepoGroupForm
41 41 from rhodecode.model.permission import PermissionModel
42 42 from rhodecode.model.repo_group import RepoGroupModel
43 43 from rhodecode.model.scm import RepoGroupList
44 44 from rhodecode.model.db import (
45 45 or_, count, func, in_filter_generator, Session, RepoGroup, User, Repository)
46 46
47 47 log = logging.getLogger(__name__)
48 48
49 49
50 50 class AdminRepoGroupsView(BaseAppView, DataGridAppView):
51 51
52 52 def load_default_context(self):
53 53 c = self._get_local_tmpl_context()
54 54
55 55 return c
56 56
57 57 def _load_form_data(self, c):
58 58 allow_empty_group = False
59 59
60 60 if self._can_create_repo_group():
61 61 # we're global admin, we're ok and we can create TOP level groups
62 62 allow_empty_group = True
63 63
64 64 # override the choices for this form, we need to filter choices
65 65 # and display only those we have ADMIN right
66 66 groups_with_admin_rights = RepoGroupList(
67 67 RepoGroup.query().all(),
68 68 perm_set=['group.admin'], extra_kwargs=dict(user=self._rhodecode_user))
69 69 c.repo_groups = RepoGroup.groups_choices(
70 70 groups=groups_with_admin_rights,
71 71 show_empty_group=allow_empty_group)
72 c.personal_repo_group = self._rhodecode_user.personal_repo_group
72 73
73 74 def _can_create_repo_group(self, parent_group_id=None):
74 75 is_admin = HasPermissionAny('hg.admin')('group create controller')
75 76 create_repo_group = HasPermissionAny(
76 77 'hg.repogroup.create.true')('group create controller')
77 78 if is_admin or (create_repo_group and not parent_group_id):
78 79 # we're global admin, or we have global repo group create
79 80 # permission
80 81 # we're ok and we can create TOP level groups
81 82 return True
82 83 elif parent_group_id:
83 84 # we check the permission if we can write to parent group
84 85 group = RepoGroup.get(parent_group_id)
85 86 group_name = group.group_name if group else None
86 87 if HasRepoGroupPermissionAny('group.admin')(
87 88 group_name, 'check if user is an admin of group'):
88 89 # we're an admin of passed in group, we're ok.
89 90 return True
90 91 else:
91 92 return False
92 93 return False
93 94
94 95 # permission check in data loading of
95 96 # `repo_group_list_data` via RepoGroupList
96 97 @LoginRequired()
97 98 @NotAnonymous()
98 99 @view_config(
99 100 route_name='repo_groups', request_method='GET',
100 101 renderer='rhodecode:templates/admin/repo_groups/repo_groups.mako')
101 102 def repo_group_list(self):
102 103 c = self.load_default_context()
103 104 return self._get_template_context(c)
104 105
105 106 # permission check inside
106 107 @LoginRequired()
107 108 @NotAnonymous()
108 109 @view_config(
109 110 route_name='repo_groups_data', request_method='GET',
110 111 renderer='json_ext', xhr=True)
111 112 def repo_group_list_data(self):
112 113 self.load_default_context()
113 114 column_map = {
114 115 'name': 'group_name_hash',
115 116 'desc': 'group_description',
116 117 'last_change': 'updated_on',
117 118 'top_level_repos': 'repos_total',
118 119 'owner': 'user_username',
119 120 }
120 121 draw, start, limit = self._extract_chunk(self.request)
121 122 search_q, order_by, order_dir = self._extract_ordering(
122 123 self.request, column_map=column_map)
123 124
124 125 _render = self.request.get_partial_renderer(
125 126 'rhodecode:templates/data_table/_dt_elements.mako')
126 127 c = _render.get_call_context()
127 128
128 129 def quick_menu(repo_group_name):
129 130 return _render('quick_repo_group_menu', repo_group_name)
130 131
131 132 def repo_group_lnk(repo_group_name):
132 133 return _render('repo_group_name', repo_group_name)
133 134
134 135 def last_change(last_change):
135 136 if isinstance(last_change, datetime.datetime) and not last_change.tzinfo:
136 137 ts = time.time()
137 138 utc_offset = (datetime.datetime.fromtimestamp(ts)
138 139 - datetime.datetime.utcfromtimestamp(ts)).total_seconds()
139 140 last_change = last_change + datetime.timedelta(seconds=utc_offset)
140 141 return _render("last_change", last_change)
141 142
142 143 def desc(desc, personal):
143 144 return _render(
144 145 'repo_group_desc', desc, personal, c.visual.stylify_metatags)
145 146
146 147 def repo_group_actions(repo_group_id, repo_group_name, gr_count):
147 148 return _render(
148 149 'repo_group_actions', repo_group_id, repo_group_name, gr_count)
149 150
150 151 def user_profile(username):
151 152 return _render('user_profile', username)
152 153
153 154 _perms = ['group.admin']
154 155 allowed_ids = [-1] + self._rhodecode_user.repo_group_acl_ids_from_stack(_perms)
155 156
156 157 repo_groups_data_total_count = RepoGroup.query()\
157 158 .filter(or_(
158 159 # generate multiple IN to fix limitation problems
159 160 *in_filter_generator(RepoGroup.group_id, allowed_ids)
160 161 )) \
161 162 .count()
162 163
163 164 repo_groups_data_total_inactive_count = RepoGroup.query()\
164 165 .filter(RepoGroup.group_id.in_(allowed_ids))\
165 166 .count()
166 167
167 168 repo_count = count(Repository.repo_id)
168 169 base_q = Session.query(
169 170 RepoGroup.group_name,
170 171 RepoGroup.group_name_hash,
171 172 RepoGroup.group_description,
172 173 RepoGroup.group_id,
173 174 RepoGroup.personal,
174 175 RepoGroup.updated_on,
175 176 User,
176 177 repo_count.label('repos_count')
177 178 ) \
178 179 .filter(or_(
179 180 # generate multiple IN to fix limitation problems
180 181 *in_filter_generator(RepoGroup.group_id, allowed_ids)
181 182 )) \
182 183 .outerjoin(Repository, Repository.group_id == RepoGroup.group_id) \
183 184 .join(User, User.user_id == RepoGroup.user_id) \
184 185 .group_by(RepoGroup, User)
185 186
186 187 if search_q:
187 188 like_expression = u'%{}%'.format(safe_unicode(search_q))
188 189 base_q = base_q.filter(or_(
189 190 RepoGroup.group_name.ilike(like_expression),
190 191 ))
191 192
192 193 repo_groups_data_total_filtered_count = base_q.count()
193 194 # the inactive isn't really used, but we still make it same as other data grids
194 195 # which use inactive (users,user groups)
195 196 repo_groups_data_total_filtered_inactive_count = repo_groups_data_total_filtered_count
196 197
197 198 sort_defined = False
198 199 if order_by == 'group_name':
199 200 sort_col = func.lower(RepoGroup.group_name)
200 201 sort_defined = True
201 202 elif order_by == 'repos_total':
202 203 sort_col = repo_count
203 204 sort_defined = True
204 205 elif order_by == 'user_username':
205 206 sort_col = User.username
206 207 else:
207 208 sort_col = getattr(RepoGroup, order_by, None)
208 209
209 210 if sort_defined or sort_col:
210 211 if order_dir == 'asc':
211 212 sort_col = sort_col.asc()
212 213 else:
213 214 sort_col = sort_col.desc()
214 215
215 216 base_q = base_q.order_by(sort_col)
216 217 base_q = base_q.offset(start).limit(limit)
217 218
218 219 # authenticated access to user groups
219 220 auth_repo_group_list = base_q.all()
220 221
221 222 repo_groups_data = []
222 223 for repo_gr in auth_repo_group_list:
223 224 row = {
224 225 "menu": quick_menu(repo_gr.group_name),
225 226 "name": repo_group_lnk(repo_gr.group_name),
226 227
227 228 "last_change": last_change(repo_gr.updated_on),
228 229
229 230 "last_changeset": "",
230 231 "last_changeset_raw": "",
231 232
232 233 "desc": desc(repo_gr.group_description, repo_gr.personal),
233 234 "owner": user_profile(repo_gr.User.username),
234 235 "top_level_repos": repo_gr.repos_count,
235 236 "action": repo_group_actions(
236 237 repo_gr.group_id, repo_gr.group_name, repo_gr.repos_count),
237 238
238 239 }
239 240
240 241 repo_groups_data.append(row)
241 242
242 243 data = ({
243 244 'draw': draw,
244 245 'data': repo_groups_data,
245 246 'recordsTotal': repo_groups_data_total_count,
246 247 'recordsTotalInactive': repo_groups_data_total_inactive_count,
247 248 'recordsFiltered': repo_groups_data_total_filtered_count,
248 249 'recordsFilteredInactive': repo_groups_data_total_filtered_inactive_count,
249 250 })
250 251
251 252 return data
252 253
253 254 @LoginRequired()
254 255 @NotAnonymous()
255 256 # perm checks inside
256 257 @view_config(
257 258 route_name='repo_group_new', request_method='GET',
258 259 renderer='rhodecode:templates/admin/repo_groups/repo_group_add.mako')
259 260 def repo_group_new(self):
260 261 c = self.load_default_context()
261 262
262 263 # perm check for admin, create_group perm or admin of parent_group
263 264 parent_group_id = safe_int(self.request.GET.get('parent_group'))
265 _gr = RepoGroup.get(parent_group_id)
264 266 if not self._can_create_repo_group(parent_group_id):
265 267 raise HTTPForbidden()
266 268
267 269 self._load_form_data(c)
268 270
269 271 defaults = {} # Future proof for default of repo group
272
273 parent_group_choice = '-1'
274 if not self._rhodecode_user.is_admin and self._rhodecode_user.personal_repo_group:
275 parent_group_choice = self._rhodecode_user.personal_repo_group
276
277 if parent_group_id and _gr:
278 if parent_group_id in [x[0] for x in c.repo_groups]:
279 parent_group_choice = safe_unicode(parent_group_id)
280
281 defaults.update({'group_parent_id': parent_group_choice})
282
270 283 data = render(
271 284 'rhodecode:templates/admin/repo_groups/repo_group_add.mako',
272 285 self._get_template_context(c), self.request)
286
273 287 html = formencode.htmlfill.render(
274 288 data,
275 289 defaults=defaults,
276 290 encoding="UTF-8",
277 291 force_defaults=False
278 292 )
279 293 return Response(html)
280 294
281 295 @LoginRequired()
282 296 @NotAnonymous()
283 297 @CSRFRequired()
284 298 # perm checks inside
285 299 @view_config(
286 300 route_name='repo_group_create', request_method='POST',
287 301 renderer='rhodecode:templates/admin/repo_groups/repo_group_add.mako')
288 302 def repo_group_create(self):
289 303 c = self.load_default_context()
290 304 _ = self.request.translate
291 305
292 306 parent_group_id = safe_int(self.request.POST.get('group_parent_id'))
293 307 can_create = self._can_create_repo_group(parent_group_id)
294 308
295 309 self._load_form_data(c)
296 310 # permissions for can create group based on parent_id are checked
297 311 # here in the Form
298 312 available_groups = map(lambda k: safe_unicode(k[0]), c.repo_groups)
299 313 repo_group_form = RepoGroupForm(
300 314 self.request.translate, available_groups=available_groups,
301 315 can_create_in_root=can_create)()
302 316
303 317 repo_group_name = self.request.POST.get('group_name')
304 318 try:
305 319 owner = self._rhodecode_user
306 320 form_result = repo_group_form.to_python(dict(self.request.POST))
307 321 copy_permissions = form_result.get('group_copy_permissions')
308 322 repo_group = RepoGroupModel().create(
309 323 group_name=form_result['group_name_full'],
310 324 group_description=form_result['group_description'],
311 325 owner=owner.user_id,
312 326 copy_permissions=form_result['group_copy_permissions']
313 327 )
314 328 Session().flush()
315 329
316 330 repo_group_data = repo_group.get_api_data()
317 331 audit_logger.store_web(
318 332 'repo_group.create', action_data={'data': repo_group_data},
319 333 user=self._rhodecode_user)
320 334
321 335 Session().commit()
322 336
323 337 _new_group_name = form_result['group_name_full']
324 338
325 339 repo_group_url = h.link_to(
326 340 _new_group_name,
327 341 h.route_path('repo_group_home', repo_group_name=_new_group_name))
328 342 h.flash(h.literal(_('Created repository group %s')
329 343 % repo_group_url), category='success')
330 344
331 345 except formencode.Invalid as errors:
332 346 data = render(
333 347 'rhodecode:templates/admin/repo_groups/repo_group_add.mako',
334 348 self._get_template_context(c), self.request)
335 349 html = formencode.htmlfill.render(
336 350 data,
337 351 defaults=errors.value,
338 352 errors=errors.error_dict or {},
339 353 prefix_error=False,
340 354 encoding="UTF-8",
341 355 force_defaults=False
342 356 )
343 357 return Response(html)
344 358 except Exception:
345 359 log.exception("Exception during creation of repository group")
346 360 h.flash(_('Error occurred during creation of repository group %s')
347 361 % repo_group_name, category='error')
348 362 raise HTTPFound(h.route_path('home'))
349 363
350 364 affected_user_ids = [self._rhodecode_user.user_id]
351 365 if copy_permissions:
352 366 user_group_perms = repo_group.permissions(expand_from_user_groups=True)
353 367 copy_perms = [perm['user_id'] for perm in user_group_perms]
354 368 # also include those newly created by copy
355 369 affected_user_ids.extend(copy_perms)
356 370 PermissionModel().trigger_permission_flush(affected_user_ids)
357 371
358 372 raise HTTPFound(
359 373 h.route_path('repo_group_home',
360 374 repo_group_name=form_result['group_name_full']))
@@ -1,266 +1,266 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 from pyramid.view import view_config
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
56 56 return c
57 57
58 58 def _load_form_data(self, c):
59 59 acl_groups = RepoGroupList(RepoGroup.query().all(),
60 60 perm_set=['group.write', 'group.admin'])
61 61 c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
62 62 c.repo_groups_choices = map(lambda k: safe_unicode(k[0]), c.repo_groups)
63 63 c.personal_repo_group = self._rhodecode_user.personal_repo_group
64 64
65 65 @LoginRequired()
66 66 @NotAnonymous()
67 67 # perms check inside
68 68 @view_config(
69 69 route_name='repos', request_method='GET',
70 70 renderer='rhodecode:templates/admin/repos/repos.mako')
71 71 def repository_list(self):
72 72 c = self.load_default_context()
73 73 return self._get_template_context(c)
74 74
75 75 @LoginRequired()
76 76 @NotAnonymous()
77 77 # perms check inside
78 78 @view_config(
79 79 route_name='repos_data', request_method='GET',
80 80 renderer='json_ext', xhr=True)
81 81 def repository_list_data(self):
82 82 self.load_default_context()
83 83 column_map = {
84 84 'name': 'repo_name',
85 85 'desc': 'description',
86 86 'last_change': 'updated_on',
87 87 'owner': 'user_username',
88 88 }
89 89 draw, start, limit = self._extract_chunk(self.request)
90 90 search_q, order_by, order_dir = self._extract_ordering(
91 91 self.request, column_map=column_map)
92 92
93 93 _perms = ['repository.admin']
94 94 allowed_ids = [-1] + self._rhodecode_user.repo_acl_ids_from_stack(_perms)
95 95
96 96 repos_data_total_count = Repository.query() \
97 97 .filter(or_(
98 98 # generate multiple IN to fix limitation problems
99 99 *in_filter_generator(Repository.repo_id, allowed_ids))
100 100 ) \
101 101 .count()
102 102
103 103 base_q = Session.query(
104 104 Repository.repo_id,
105 105 Repository.repo_name,
106 106 Repository.description,
107 107 Repository.repo_type,
108 108 Repository.repo_state,
109 109 Repository.private,
110 110 Repository.archived,
111 111 Repository.fork,
112 112 Repository.updated_on,
113 113 Repository._changeset_cache,
114 114 User,
115 115 ) \
116 116 .filter(or_(
117 117 # generate multiple IN to fix limitation problems
118 118 *in_filter_generator(Repository.repo_id, allowed_ids))
119 119 ) \
120 120 .join(User, User.user_id == Repository.user_id) \
121 121 .group_by(Repository, User)
122 122
123 123 if search_q:
124 124 like_expression = u'%{}%'.format(safe_unicode(search_q))
125 125 base_q = base_q.filter(or_(
126 126 Repository.repo_name.ilike(like_expression),
127 127 ))
128 128
129 129 repos_data_total_filtered_count = base_q.count()
130 130
131 131 sort_defined = False
132 132 if order_by == 'repo_name':
133 133 sort_col = func.lower(Repository.repo_name)
134 134 sort_defined = True
135 135 elif order_by == 'user_username':
136 136 sort_col = User.username
137 137 else:
138 138 sort_col = getattr(Repository, order_by, None)
139 139
140 140 if sort_defined or sort_col:
141 141 if order_dir == 'asc':
142 142 sort_col = sort_col.asc()
143 143 else:
144 144 sort_col = sort_col.desc()
145 145
146 146 base_q = base_q.order_by(sort_col)
147 147 base_q = base_q.offset(start).limit(limit)
148 148
149 149 repos_list = base_q.all()
150 150
151 151 repos_data = RepoModel().get_repos_as_dict(
152 152 repo_list=repos_list, admin=True, super_user_actions=True)
153 153
154 154 data = ({
155 155 'draw': draw,
156 156 'data': repos_data,
157 157 'recordsTotal': repos_data_total_count,
158 158 'recordsFiltered': repos_data_total_filtered_count,
159 159 })
160 160 return data
161 161
162 162 @LoginRequired()
163 163 @NotAnonymous()
164 164 # perms check inside
165 165 @view_config(
166 166 route_name='repo_new', request_method='GET',
167 167 renderer='rhodecode:templates/admin/repos/repo_add.mako')
168 168 def repository_new(self):
169 169 c = self.load_default_context()
170 170
171 171 new_repo = self.request.GET.get('repo', '')
172 parent_group = safe_int(self.request.GET.get('parent_group'))
173 _gr = RepoGroup.get(parent_group)
172 parent_group_id = safe_int(self.request.GET.get('parent_group'))
173 _gr = RepoGroup.get(parent_group_id)
174 174
175 175 if not HasPermissionAny('hg.admin', 'hg.create.repository')():
176 176 # you're not super admin nor have global create permissions,
177 177 # but maybe you have at least write permission to a parent group ?
178 178
179 179 gr_name = _gr.group_name if _gr else None
180 180 # create repositories with write permission on group is set to true
181 181 create_on_write = HasPermissionAny('hg.create.write_on_repogroup.true')()
182 182 group_admin = HasRepoGroupPermissionAny('group.admin')(group_name=gr_name)
183 183 group_write = HasRepoGroupPermissionAny('group.write')(group_name=gr_name)
184 184 if not (group_admin or (group_write and create_on_write)):
185 185 raise HTTPForbidden()
186 186
187 187 self._load_form_data(c)
188 188 c.new_repo = repo_name_slug(new_repo)
189 189
190 190 # apply the defaults from defaults page
191 191 defaults = SettingsModel().get_default_repo_settings(strip_prefix=True)
192 192 # set checkbox to autochecked
193 193 defaults['repo_copy_permissions'] = True
194 194
195 195 parent_group_choice = '-1'
196 196 if not self._rhodecode_user.is_admin and self._rhodecode_user.personal_repo_group:
197 197 parent_group_choice = self._rhodecode_user.personal_repo_group
198 198
199 if parent_group and _gr:
200 if parent_group in [x[0] for x in c.repo_groups]:
201 parent_group_choice = safe_unicode(parent_group)
199 if parent_group_id and _gr:
200 if parent_group_id in [x[0] for x in c.repo_groups]:
201 parent_group_choice = safe_unicode(parent_group_id)
202 202
203 203 defaults.update({'repo_group': parent_group_choice})
204 204
205 205 data = render('rhodecode:templates/admin/repos/repo_add.mako',
206 206 self._get_template_context(c), self.request)
207 207 html = formencode.htmlfill.render(
208 208 data,
209 209 defaults=defaults,
210 210 encoding="UTF-8",
211 211 force_defaults=False
212 212 )
213 213 return Response(html)
214 214
215 215 @LoginRequired()
216 216 @NotAnonymous()
217 217 @CSRFRequired()
218 218 # perms check inside
219 219 @view_config(
220 220 route_name='repo_create', request_method='POST',
221 221 renderer='rhodecode:templates/admin/repos/repos.mako')
222 222 def repository_create(self):
223 223 c = self.load_default_context()
224 224
225 225 form_result = {}
226 226 self._load_form_data(c)
227 227
228 228 try:
229 229 # CanWriteToGroup validators checks permissions of this POST
230 230 form = RepoForm(
231 231 self.request.translate, repo_groups=c.repo_groups_choices)()
232 232 form_result = form.to_python(dict(self.request.POST))
233 233 copy_permissions = form_result.get('repo_copy_permissions')
234 234 # create is done sometimes async on celery, db transaction
235 235 # management is handled there.
236 236 task = RepoModel().create(form_result, self._rhodecode_user.user_id)
237 237 task_id = get_task_id(task)
238 238 except formencode.Invalid as errors:
239 239 data = render('rhodecode:templates/admin/repos/repo_add.mako',
240 240 self._get_template_context(c), self.request)
241 241 html = formencode.htmlfill.render(
242 242 data,
243 243 defaults=errors.value,
244 244 errors=errors.error_dict or {},
245 245 prefix_error=False,
246 246 encoding="UTF-8",
247 247 force_defaults=False
248 248 )
249 249 return Response(html)
250 250
251 251 except Exception as e:
252 252 msg = self._log_creation_exception(e, form_result.get('repo_name'))
253 253 h.flash(msg, category='error')
254 254 raise HTTPFound(h.route_path('home'))
255 255
256 256 repo_name = form_result.get('repo_name_full')
257 257
258 258 affected_user_ids = [self._rhodecode_user.user_id]
259 259 if copy_permissions:
260 260 # permission flush is done in repo creating
261 261 pass
262 262 PermissionModel().trigger_permission_flush(affected_user_ids)
263 263
264 264 raise HTTPFound(
265 265 h.route_path('repo_creating', repo_name=repo_name,
266 266 _query=dict(task_id=task_id)))
@@ -1,111 +1,122 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.mako"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Add repository group')}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11 <%def name="breadcrumbs_links()">
12 12 ${h.link_to(_('Admin'),h.route_path('admin_home'))}
13 13 &raquo;
14 14 ${h.link_to(_('Repository groups'),h.route_path('repo_groups'))}
15 15 &raquo;
16 16 ${_('Add Repository Group')}
17 17 </%def>
18 18
19 19 <%def name="menu_bar_nav()">
20 20 ${self.menu_items(active='admin')}
21 21 </%def>
22 22
23 23 <%def name="menu_bar_subnav()">
24 24 ${self.admin_menu(active='repository_groups')}
25 25 </%def>
26 26
27 27 <%def name="main()">
28 28 <div class="box">
29 29 ${h.secure_form(h.route_path('repo_group_create'), request=request)}
30 30 <div class="form">
31 31 <!-- fields -->
32 32 <div class="fields">
33 33 <div class="field">
34 34 <div class="label">
35 35 <label for="group_name">${_('Group name')}:</label>
36 36 </div>
37 37 <div class="input">
38 38 ${h.text('group_name', class_="medium")}
39 39 </div>
40 40 </div>
41 41
42 42 <div class="field">
43 43 <div class="label">
44 44 <label for="group_parent_id">${_('Repository group')}:</label>
45 45 </div>
46 46 <div class="select">
47 ${h.select('group_parent_id',request.GET.get('parent_group'),c.repo_groups,class_="medium")}
47 ${h.select('group_parent_id', request.GET.get('parent_group'),c.repo_groups,class_="medium")}
48 % if c.personal_repo_group:
49 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
50 ${_('Select my personal group ({})').format(c.personal_repo_group.group_name)}
51 </a>
52 % endif
48 53 </div>
49 54 </div>
50 55
51 56 <div class="field">
52 57 <div class="label">
53 58 <label for="group_description">${_('Description')}:</label>
54 59 </div>
55 60 <div class="textarea editor">
56 61 ${h.textarea('group_description',cols=23,rows=5,class_="medium")}
57 62 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
58 63 <span class="help-block">
59 64 % if c.visual.stylify_metatags:
60 65 ${_('Plain text format with {metatags} support.').format(metatags=metatags_url)|n}
61 66 % else:
62 67 ${_('Plain text format.')}
63 68 % endif
64 69 </span>
65 70 <span id="meta-tags-desc" style="display: none">
66 71 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
67 72 ${dt.metatags_help()}
68 73 </span>
69 74 </div>
70 75 </div>
71 76
72 77 <div id="copy_perms" class="field">
73 78 <div class="label label-checkbox">
74 79 <label for="group_copy_permissions">${_('Copy Parent Group Permissions')}:</label>
75 80 </div>
76 81 <div class="checkboxes">
77 82 ${h.checkbox('group_copy_permissions', value="True", checked="checked")}
78 83 <span class="help-block">${_('Copy permissions from parent repository group.')}</span>
79 84 </div>
80 85 </div>
81 86
82 87 <div class="buttons">
83 88 ${h.submit('save',_('Create Repository Group'),class_="btn")}
84 89 </div>
85 90 </div>
86 91 </div>
87 92 ${h.end_form()}
88 93 </div>
89 94 <script>
90 95 $(document).ready(function(){
91 96 var setCopyPermsOption = function(group_val){
92 97 if(group_val !== "-1"){
93 98 $('#copy_perms').show()
94 99 }
95 100 else{
96 101 $('#copy_perms').hide();
97 102 }
98 103 };
99 104 $("#group_parent_id").select2({
100 105 'containerCssClass': "drop-menu",
101 106 'dropdownCssClass': "drop-menu-dropdown",
102 107 'dropdownAutoWidth': true
103 108 });
104 109 setCopyPermsOption($('#group_parent_id').val());
105 110 $("#group_parent_id").on("change", function(e) {
106 111 setCopyPermsOption(e.val)
107 112 });
108 113 $('#group_name').focus();
114
115 $('#select_my_group').on('click', function(e){
116 e.preventDefault();
117 $("#group_parent_id").val($(this).data('personalGroupId')).trigger("change");
118 })
119
109 120 })
110 121 </script>
111 122 </%def>
@@ -1,169 +1,169 b''
1 1 ## -*- coding: utf-8 -*-
2 2
3 3 ${h.secure_form(h.route_path('repo_create'), request=request)}
4 4 <div class="form">
5 5 <!-- fields -->
6 6 <div class="fields">
7 7 <div class="field">
8 8 <div class="label">
9 9 <label for="repo_name">${_('Repository name')}:</label>
10 10 </div>
11 11 <div class="input">
12 12 ${h.text('repo_name', class_="medium")}
13 13 <div class="info-block">
14 14 <a id="remote_clone_toggle" href="#">${_('Import Existing Repository ?')}</a>
15 15 </div>
16 16 %if not c.rhodecode_user.is_admin:
17 17 ${h.hidden('user_created',True)}
18 18 %endif
19 19 </div>
20 20 </div>
21 21 <div id="remote_clone" class="field" style="display: none;">
22 22 <div class="label">
23 23 <label for="clone_uri">${_('Clone from')}:</label>
24 24 </div>
25 25 <div class="input">
26 26 ${h.text('clone_uri', class_="medium")}
27 27 <span class="help-block">
28 28 <pre>
29 29 - The repository must be accessible over http:// or https://
30 30 - For Git projects it's recommended appending .git to the end of clone url.
31 31 - Make sure to select proper repository type from the below selector before importing it.
32 32 - If your HTTP[S] repository is not publicly accessible,
33 33 add authentication information to the URL: https://username:password@server.company.com/repo-name.
34 34 - The Git LFS/Mercurial Largefiles objects will not be imported.
35 35 - For very large repositories, it's recommended to manually copy them into the
36 36 RhodeCode <a href="${h.route_path('admin_settings_vcs', _anchor='vcs-storage-options')}">storage location</a> and run <a href="${h.route_path('admin_settings_mapping')}">Remap and Rescan</a>.
37 37 </pre>
38 38 </span>
39 39 </div>
40 40 </div>
41 41 <div class="field">
42 42 <div class="label">
43 43 <label for="repo_group">${_('Repository group')}:</label>
44 44 </div>
45 45 <div class="select">
46 46 ${h.select('repo_group',request.GET.get('parent_group'),c.repo_groups,class_="medium")}
47 47 % if c.personal_repo_group:
48 48 <a class="btn" href="#" id="select_my_group" data-personal-group-id="${c.personal_repo_group.group_id}">
49 ${_('Select my personal group (%(repo_group_name)s)') % {'repo_group_name': c.personal_repo_group.group_name}}
49 ${_('Select my personal group ({})').format(c.personal_repo_group.group_name)}
50 50 </a>
51 51 % endif
52 52 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
53 53 </div>
54 54 </div>
55 55
56 56 <div class="field">
57 57 <div class="label">
58 58 <label for="repo_type">${_('Type')}:</label>
59 59 </div>
60 60 <div class="fields repo-type-radio">
61 61
62 62
63 63 % for backend in c.backends:
64 64 % if loop.index == 0:
65 65 <input id="repo_type_${backend}" name="repo_type" type="radio" value="${backend}" checked="checked"/>
66 66 % else:
67 67 <input id="repo_type_${backend}" name="repo_type" type="radio" value="${backend}" />
68 68 % endif
69 69
70 70 <label for="repo_type_${backend}">
71 71 <i class="icon-${backend}" style="font-size: 16px"></i>
72 72 ${backend.upper()}
73 73 </label>
74 74
75 75 % endfor
76 76
77 77
78 78 <span class="help-block">${_('Set the type of repository to create.')}</span>
79 79 </div>
80 80 </div>
81 81 <div class="field">
82 82 <div class="label">
83 83 <label for="repo_description">${_('Description')}:</label>
84 84 </div>
85 85 <div class="textarea editor">
86 86 ${h.textarea('repo_description',cols=23,rows=5,class_="medium")}
87 87 <% metatags_url = h.literal('''<a href="#metatagsShow" onclick="$('#meta-tags-desc').toggle();return false">meta-tags</a>''') %>
88 88 <span class="help-block">
89 89 % if c.visual.stylify_metatags:
90 90 ${_('Plain text format with {metatags} support.').format(metatags=metatags_url)|n}
91 91 % else:
92 92 ${_('Plain text format.')}
93 93 % endif
94 94 ${_('Add a README file for longer descriptions')}
95 95 </span>
96 96 <span id="meta-tags-desc" style="display: none">
97 97 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
98 98 ${dt.metatags_help()}
99 99 </span>
100 100 </div>
101 101 </div>
102 102 <div id="copy_perms" class="field">
103 103 <div class="label label-checkbox">
104 104 <label for="repo_copy_permissions">${_('Copy Parent Group Permissions')}:</label>
105 105 </div>
106 106 <div class="checkboxes">
107 107 ${h.checkbox('repo_copy_permissions', value="True", checked="checked")}
108 108 <span class="help-block">${_('Copy permissions from parent repository group.')}</span>
109 109 </div>
110 110 </div>
111 111 <div class="field">
112 112 <div class="label label-checkbox">
113 113 <label for="repo_private">${_('Private Repository')}:</label>
114 114 </div>
115 115 <div class="checkboxes">
116 116 ${h.checkbox('repo_private',value="True")}
117 117 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
118 118 </div>
119 119 </div>
120 120 <div class="buttons">
121 121 ${h.submit('save',_('Create Repository'),class_="btn")}
122 122 </div>
123 123 </div>
124 124 </div>
125 125 <script>
126 126 $(document).ready(function(){
127 127 var setCopyPermsOption = function(group_val){
128 128 if(group_val != "-1"){
129 129 $('#copy_perms').show()
130 130 }
131 131 else{
132 132 $('#copy_perms').hide();
133 133 }
134 134 };
135 135
136 136 $('#remote_clone_toggle').on('click', function(e){
137 137 $('#remote_clone').show();
138 138 e.preventDefault();
139 139 });
140 140
141 141 if($('#remote_clone input').hasClass('error')){
142 142 $('#remote_clone').show();
143 143 }
144 144 if($('#remote_clone input').val()){
145 145 $('#remote_clone').show();
146 146 }
147 147
148 148 $("#repo_group").select2({
149 149 'containerCssClass': "drop-menu",
150 150 'dropdownCssClass': "drop-menu-dropdown",
151 151 'dropdownAutoWidth': true,
152 152 'width': "resolve"
153 153 });
154 154
155 155 setCopyPermsOption($('#repo_group').val());
156 156 $("#repo_group").on("change", function(e) {
157 157 setCopyPermsOption(e.val)
158 158 });
159 159
160 160 $('#repo_name').focus();
161 161
162 162 $('#select_my_group').on('click', function(e){
163 163 e.preventDefault();
164 164 $("#repo_group").val($(this).data('personalGroupId')).trigger("change");
165 165 })
166 166
167 167 })
168 168 </script>
169 169 ${h.end_form()}
General Comments 0
You need to be logged in to leave comments. Login now