##// END OF EJS Templates
pyramid: moved add_route_requirements into pyramid base app....
marcink -
r1928:d7d26d76 default
parent child Browse files
Show More
@@ -1,385 +1,409 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import time
21 import time
22 import logging
22 import logging
23
23
24 from pyramid.httpexceptions import HTTPFound
24 from pyramid.httpexceptions import HTTPFound
25
25
26 from rhodecode.lib import helpers as h
26 from rhodecode.lib import helpers as h
27 from rhodecode.lib.utils2 import StrictAttributeDict, safe_int, datetime_to_time
27 from rhodecode.lib.utils2 import StrictAttributeDict, safe_int, datetime_to_time
28 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
28 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
29 from rhodecode.model import repo
29 from rhodecode.model import repo
30 from rhodecode.model import repo_group
30 from rhodecode.model import repo_group
31 from rhodecode.model.db import User
31 from rhodecode.model.db import User
32 from rhodecode.model.scm import ScmModel
32 from rhodecode.model.scm import ScmModel
33
33
34 log = logging.getLogger(__name__)
34 log = logging.getLogger(__name__)
35
35
36
36
37 ADMIN_PREFIX = '/_admin'
37 ADMIN_PREFIX = '/_admin'
38 STATIC_FILE_PREFIX = '/_static'
38 STATIC_FILE_PREFIX = '/_static'
39
39
40 URL_NAME_REQUIREMENTS = {
41 # group name can have a slash in them, but they must not end with a slash
42 'group_name': r'.*?[^/]',
43 'repo_group_name': r'.*?[^/]',
44 # repo names can have a slash in them, but they must not end with a slash
45 'repo_name': r'.*?[^/]',
46 # file path eats up everything at the end
47 'f_path': r'.*',
48 # reference types
49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
51 }
52
40
53
41 def add_route_with_slash(config,name, pattern, **kw):
54 def add_route_with_slash(config,name, pattern, **kw):
42 config.add_route(name, pattern, **kw)
55 config.add_route(name, pattern, **kw)
43 if not pattern.endswith('/'):
56 if not pattern.endswith('/'):
44 config.add_route(name + '_slash', pattern + '/', **kw)
57 config.add_route(name + '_slash', pattern + '/', **kw)
45
58
46
59
60 def add_route_requirements(route_path, requirements=URL_NAME_REQUIREMENTS):
61 """
62 Adds regex requirements to pyramid routes using a mapping dict
63 e.g::
64 add_route_requirements('{repo_name}/settings')
65 """
66 for key, regex in requirements.items():
67 route_path = route_path.replace('{%s}' % key, '{%s:%s}' % (key, regex))
68 return route_path
69
70
47 def get_format_ref_id(repo):
71 def get_format_ref_id(repo):
48 """Returns a `repo` specific reference formatter function"""
72 """Returns a `repo` specific reference formatter function"""
49 if h.is_svn(repo):
73 if h.is_svn(repo):
50 return _format_ref_id_svn
74 return _format_ref_id_svn
51 else:
75 else:
52 return _format_ref_id
76 return _format_ref_id
53
77
54
78
55 def _format_ref_id(name, raw_id):
79 def _format_ref_id(name, raw_id):
56 """Default formatting of a given reference `name`"""
80 """Default formatting of a given reference `name`"""
57 return name
81 return name
58
82
59
83
60 def _format_ref_id_svn(name, raw_id):
84 def _format_ref_id_svn(name, raw_id):
61 """Special way of formatting a reference for Subversion including path"""
85 """Special way of formatting a reference for Subversion including path"""
62 return '%s@%s' % (name, raw_id)
86 return '%s@%s' % (name, raw_id)
63
87
64
88
65 class TemplateArgs(StrictAttributeDict):
89 class TemplateArgs(StrictAttributeDict):
66 pass
90 pass
67
91
68
92
69 class BaseAppView(object):
93 class BaseAppView(object):
70
94
71 def __init__(self, context, request):
95 def __init__(self, context, request):
72 self.request = request
96 self.request = request
73 self.context = context
97 self.context = context
74 self.session = request.session
98 self.session = request.session
75 self._rhodecode_user = request.user # auth user
99 self._rhodecode_user = request.user # auth user
76 self._rhodecode_db_user = self._rhodecode_user.get_instance()
100 self._rhodecode_db_user = self._rhodecode_user.get_instance()
77 self._maybe_needs_password_change(
101 self._maybe_needs_password_change(
78 request.matched_route.name, self._rhodecode_db_user)
102 request.matched_route.name, self._rhodecode_db_user)
79
103
80 def _maybe_needs_password_change(self, view_name, user_obj):
104 def _maybe_needs_password_change(self, view_name, user_obj):
81 log.debug('Checking if user %s needs password change on view %s',
105 log.debug('Checking if user %s needs password change on view %s',
82 user_obj, view_name)
106 user_obj, view_name)
83 skip_user_views = [
107 skip_user_views = [
84 'logout', 'login',
108 'logout', 'login',
85 'my_account_password', 'my_account_password_update'
109 'my_account_password', 'my_account_password_update'
86 ]
110 ]
87
111
88 if not user_obj:
112 if not user_obj:
89 return
113 return
90
114
91 if user_obj.username == User.DEFAULT_USER:
115 if user_obj.username == User.DEFAULT_USER:
92 return
116 return
93
117
94 now = time.time()
118 now = time.time()
95 should_change = user_obj.user_data.get('force_password_change')
119 should_change = user_obj.user_data.get('force_password_change')
96 change_after = safe_int(should_change) or 0
120 change_after = safe_int(should_change) or 0
97 if should_change and now > change_after:
121 if should_change and now > change_after:
98 log.debug('User %s requires password change', user_obj)
122 log.debug('User %s requires password change', user_obj)
99 h.flash('You are required to change your password', 'warning',
123 h.flash('You are required to change your password', 'warning',
100 ignore_duplicate=True)
124 ignore_duplicate=True)
101
125
102 if view_name not in skip_user_views:
126 if view_name not in skip_user_views:
103 raise HTTPFound(
127 raise HTTPFound(
104 self.request.route_path('my_account_password'))
128 self.request.route_path('my_account_password'))
105
129
106 def _get_local_tmpl_context(self, include_app_defaults=False):
130 def _get_local_tmpl_context(self, include_app_defaults=False):
107 c = TemplateArgs()
131 c = TemplateArgs()
108 c.auth_user = self.request.user
132 c.auth_user = self.request.user
109 # TODO(marcink): migrate the usage of c.rhodecode_user to c.auth_user
133 # TODO(marcink): migrate the usage of c.rhodecode_user to c.auth_user
110 c.rhodecode_user = self.request.user
134 c.rhodecode_user = self.request.user
111
135
112 if include_app_defaults:
136 if include_app_defaults:
113 # NOTE(marcink): after full pyramid migration include_app_defaults
137 # NOTE(marcink): after full pyramid migration include_app_defaults
114 # should be turned on by default
138 # should be turned on by default
115 from rhodecode.lib.base import attach_context_attributes
139 from rhodecode.lib.base import attach_context_attributes
116 attach_context_attributes(c, self.request, self.request.user.user_id)
140 attach_context_attributes(c, self.request, self.request.user.user_id)
117
141
118 return c
142 return c
119
143
120 def _register_global_c(self, tmpl_args):
144 def _register_global_c(self, tmpl_args):
121 """
145 """
122 Registers attributes to pylons global `c`
146 Registers attributes to pylons global `c`
123 """
147 """
124
148
125 # TODO(marcink): remove once pyramid migration is finished
149 # TODO(marcink): remove once pyramid migration is finished
126 from pylons import tmpl_context as c
150 from pylons import tmpl_context as c
127 try:
151 try:
128 for k, v in tmpl_args.items():
152 for k, v in tmpl_args.items():
129 setattr(c, k, v)
153 setattr(c, k, v)
130 except TypeError:
154 except TypeError:
131 log.exception('Failed to register pylons C')
155 log.exception('Failed to register pylons C')
132 pass
156 pass
133
157
134 def _get_template_context(self, tmpl_args):
158 def _get_template_context(self, tmpl_args):
135 self._register_global_c(tmpl_args)
159 self._register_global_c(tmpl_args)
136
160
137 local_tmpl_args = {
161 local_tmpl_args = {
138 'defaults': {},
162 'defaults': {},
139 'errors': {},
163 'errors': {},
140 # register a fake 'c' to be used in templates instead of global
164 # register a fake 'c' to be used in templates instead of global
141 # pylons c, after migration to pyramid we should rename it to 'c'
165 # pylons c, after migration to pyramid we should rename it to 'c'
142 # make sure we replace usage of _c in templates too
166 # make sure we replace usage of _c in templates too
143 '_c': tmpl_args
167 '_c': tmpl_args
144 }
168 }
145 local_tmpl_args.update(tmpl_args)
169 local_tmpl_args.update(tmpl_args)
146 return local_tmpl_args
170 return local_tmpl_args
147
171
148 def load_default_context(self):
172 def load_default_context(self):
149 """
173 """
150 example:
174 example:
151
175
152 def load_default_context(self):
176 def load_default_context(self):
153 c = self._get_local_tmpl_context()
177 c = self._get_local_tmpl_context()
154 c.custom_var = 'foobar'
178 c.custom_var = 'foobar'
155 self._register_global_c(c)
179 self._register_global_c(c)
156 return c
180 return c
157 """
181 """
158 raise NotImplementedError('Needs implementation in view class')
182 raise NotImplementedError('Needs implementation in view class')
159
183
160
184
161 class RepoAppView(BaseAppView):
185 class RepoAppView(BaseAppView):
162
186
163 def __init__(self, context, request):
187 def __init__(self, context, request):
164 super(RepoAppView, self).__init__(context, request)
188 super(RepoAppView, self).__init__(context, request)
165 self.db_repo = request.db_repo
189 self.db_repo = request.db_repo
166 self.db_repo_name = self.db_repo.repo_name
190 self.db_repo_name = self.db_repo.repo_name
167 self.db_repo_pull_requests = ScmModel().get_pull_requests(self.db_repo)
191 self.db_repo_pull_requests = ScmModel().get_pull_requests(self.db_repo)
168
192
169 def _handle_missing_requirements(self, error):
193 def _handle_missing_requirements(self, error):
170 log.error(
194 log.error(
171 'Requirements are missing for repository %s: %s',
195 'Requirements are missing for repository %s: %s',
172 self.db_repo_name, error.message)
196 self.db_repo_name, error.message)
173
197
174 def _get_local_tmpl_context(self, include_app_defaults=False):
198 def _get_local_tmpl_context(self, include_app_defaults=False):
175 c = super(RepoAppView, self)._get_local_tmpl_context(
199 c = super(RepoAppView, self)._get_local_tmpl_context(
176 include_app_defaults=include_app_defaults)
200 include_app_defaults=include_app_defaults)
177
201
178 # register common vars for this type of view
202 # register common vars for this type of view
179 c.rhodecode_db_repo = self.db_repo
203 c.rhodecode_db_repo = self.db_repo
180 c.repo_name = self.db_repo_name
204 c.repo_name = self.db_repo_name
181 c.repository_pull_requests = self.db_repo_pull_requests
205 c.repository_pull_requests = self.db_repo_pull_requests
182
206
183 c.repository_requirements_missing = False
207 c.repository_requirements_missing = False
184 try:
208 try:
185 self.rhodecode_vcs_repo = self.db_repo.scm_instance()
209 self.rhodecode_vcs_repo = self.db_repo.scm_instance()
186 except RepositoryRequirementError as e:
210 except RepositoryRequirementError as e:
187 c.repository_requirements_missing = True
211 c.repository_requirements_missing = True
188 self._handle_missing_requirements(e)
212 self._handle_missing_requirements(e)
189
213
190 return c
214 return c
191
215
192
216
193 class DataGridAppView(object):
217 class DataGridAppView(object):
194 """
218 """
195 Common class to have re-usable grid rendering components
219 Common class to have re-usable grid rendering components
196 """
220 """
197
221
198 def _extract_ordering(self, request, column_map=None):
222 def _extract_ordering(self, request, column_map=None):
199 column_map = column_map or {}
223 column_map = column_map or {}
200 column_index = safe_int(request.GET.get('order[0][column]'))
224 column_index = safe_int(request.GET.get('order[0][column]'))
201 order_dir = request.GET.get(
225 order_dir = request.GET.get(
202 'order[0][dir]', 'desc')
226 'order[0][dir]', 'desc')
203 order_by = request.GET.get(
227 order_by = request.GET.get(
204 'columns[%s][data][sort]' % column_index, 'name_raw')
228 'columns[%s][data][sort]' % column_index, 'name_raw')
205
229
206 # translate datatable to DB columns
230 # translate datatable to DB columns
207 order_by = column_map.get(order_by) or order_by
231 order_by = column_map.get(order_by) or order_by
208
232
209 search_q = request.GET.get('search[value]')
233 search_q = request.GET.get('search[value]')
210 return search_q, order_by, order_dir
234 return search_q, order_by, order_dir
211
235
212 def _extract_chunk(self, request):
236 def _extract_chunk(self, request):
213 start = safe_int(request.GET.get('start'), 0)
237 start = safe_int(request.GET.get('start'), 0)
214 length = safe_int(request.GET.get('length'), 25)
238 length = safe_int(request.GET.get('length'), 25)
215 draw = safe_int(request.GET.get('draw'))
239 draw = safe_int(request.GET.get('draw'))
216 return draw, start, length
240 return draw, start, length
217
241
218
242
219 class BaseReferencesView(RepoAppView):
243 class BaseReferencesView(RepoAppView):
220 """
244 """
221 Base for reference view for branches, tags and bookmarks.
245 Base for reference view for branches, tags and bookmarks.
222 """
246 """
223 def load_default_context(self):
247 def load_default_context(self):
224 c = self._get_local_tmpl_context()
248 c = self._get_local_tmpl_context()
225
249
226 # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
250 # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
227 c.repo_info = self.db_repo
251 c.repo_info = self.db_repo
228
252
229 self._register_global_c(c)
253 self._register_global_c(c)
230 return c
254 return c
231
255
232 def load_refs_context(self, ref_items, partials_template):
256 def load_refs_context(self, ref_items, partials_template):
233 _render = self.request.get_partial_renderer(partials_template)
257 _render = self.request.get_partial_renderer(partials_template)
234 pre_load = ["author", "date", "message"]
258 pre_load = ["author", "date", "message"]
235
259
236 is_svn = h.is_svn(self.rhodecode_vcs_repo)
260 is_svn = h.is_svn(self.rhodecode_vcs_repo)
237 is_hg = h.is_hg(self.rhodecode_vcs_repo)
261 is_hg = h.is_hg(self.rhodecode_vcs_repo)
238
262
239 format_ref_id = get_format_ref_id(self.rhodecode_vcs_repo)
263 format_ref_id = get_format_ref_id(self.rhodecode_vcs_repo)
240
264
241 closed_refs = {}
265 closed_refs = {}
242 if is_hg:
266 if is_hg:
243 closed_refs = self.rhodecode_vcs_repo.branches_closed
267 closed_refs = self.rhodecode_vcs_repo.branches_closed
244
268
245 data = []
269 data = []
246 for ref_name, commit_id in ref_items:
270 for ref_name, commit_id in ref_items:
247 commit = self.rhodecode_vcs_repo.get_commit(
271 commit = self.rhodecode_vcs_repo.get_commit(
248 commit_id=commit_id, pre_load=pre_load)
272 commit_id=commit_id, pre_load=pre_load)
249 closed = ref_name in closed_refs
273 closed = ref_name in closed_refs
250
274
251 # TODO: johbo: Unify generation of reference links
275 # TODO: johbo: Unify generation of reference links
252 use_commit_id = '/' in ref_name or is_svn
276 use_commit_id = '/' in ref_name or is_svn
253
277
254 if use_commit_id:
278 if use_commit_id:
255 files_url = h.route_path(
279 files_url = h.route_path(
256 'repo_files',
280 'repo_files',
257 repo_name=self.db_repo_name,
281 repo_name=self.db_repo_name,
258 f_path=ref_name if is_svn else '',
282 f_path=ref_name if is_svn else '',
259 commit_id=commit_id)
283 commit_id=commit_id)
260
284
261 else:
285 else:
262 files_url = h.route_path(
286 files_url = h.route_path(
263 'repo_files',
287 'repo_files',
264 repo_name=self.db_repo_name,
288 repo_name=self.db_repo_name,
265 f_path=ref_name if is_svn else '',
289 f_path=ref_name if is_svn else '',
266 commit_id=ref_name,
290 commit_id=ref_name,
267 _query=dict(at=ref_name))
291 _query=dict(at=ref_name))
268
292
269 data.append({
293 data.append({
270 "name": _render('name', ref_name, files_url, closed),
294 "name": _render('name', ref_name, files_url, closed),
271 "name_raw": ref_name,
295 "name_raw": ref_name,
272 "date": _render('date', commit.date),
296 "date": _render('date', commit.date),
273 "date_raw": datetime_to_time(commit.date),
297 "date_raw": datetime_to_time(commit.date),
274 "author": _render('author', commit.author),
298 "author": _render('author', commit.author),
275 "commit": _render(
299 "commit": _render(
276 'commit', commit.message, commit.raw_id, commit.idx),
300 'commit', commit.message, commit.raw_id, commit.idx),
277 "commit_raw": commit.idx,
301 "commit_raw": commit.idx,
278 "compare": _render(
302 "compare": _render(
279 'compare', format_ref_id(ref_name, commit.raw_id)),
303 'compare', format_ref_id(ref_name, commit.raw_id)),
280 })
304 })
281
305
282 return data
306 return data
283
307
284
308
285 class RepoRoutePredicate(object):
309 class RepoRoutePredicate(object):
286 def __init__(self, val, config):
310 def __init__(self, val, config):
287 self.val = val
311 self.val = val
288
312
289 def text(self):
313 def text(self):
290 return 'repo_route = %s' % self.val
314 return 'repo_route = %s' % self.val
291
315
292 phash = text
316 phash = text
293
317
294 def __call__(self, info, request):
318 def __call__(self, info, request):
295
319
296 if hasattr(request, 'vcs_call'):
320 if hasattr(request, 'vcs_call'):
297 # skip vcs calls
321 # skip vcs calls
298 return
322 return
299
323
300 repo_name = info['match']['repo_name']
324 repo_name = info['match']['repo_name']
301 repo_model = repo.RepoModel()
325 repo_model = repo.RepoModel()
302 by_name_match = repo_model.get_by_repo_name(repo_name, cache=True)
326 by_name_match = repo_model.get_by_repo_name(repo_name, cache=True)
303
327
304 if by_name_match:
328 if by_name_match:
305 # register this as request object we can re-use later
329 # register this as request object we can re-use later
306 request.db_repo = by_name_match
330 request.db_repo = by_name_match
307 return True
331 return True
308
332
309 by_id_match = repo_model.get_repo_by_id(repo_name)
333 by_id_match = repo_model.get_repo_by_id(repo_name)
310 if by_id_match:
334 if by_id_match:
311 request.db_repo = by_id_match
335 request.db_repo = by_id_match
312 return True
336 return True
313
337
314 return False
338 return False
315
339
316
340
317 class RepoTypeRoutePredicate(object):
341 class RepoTypeRoutePredicate(object):
318 def __init__(self, val, config):
342 def __init__(self, val, config):
319 self.val = val or ['hg', 'git', 'svn']
343 self.val = val or ['hg', 'git', 'svn']
320
344
321 def text(self):
345 def text(self):
322 return 'repo_accepted_type = %s' % self.val
346 return 'repo_accepted_type = %s' % self.val
323
347
324 phash = text
348 phash = text
325
349
326 def __call__(self, info, request):
350 def __call__(self, info, request):
327 if hasattr(request, 'vcs_call'):
351 if hasattr(request, 'vcs_call'):
328 # skip vcs calls
352 # skip vcs calls
329 return
353 return
330
354
331 rhodecode_db_repo = request.db_repo
355 rhodecode_db_repo = request.db_repo
332
356
333 log.debug(
357 log.debug(
334 '%s checking repo type for %s in %s',
358 '%s checking repo type for %s in %s',
335 self.__class__.__name__, rhodecode_db_repo.repo_type, self.val)
359 self.__class__.__name__, rhodecode_db_repo.repo_type, self.val)
336
360
337 if rhodecode_db_repo.repo_type in self.val:
361 if rhodecode_db_repo.repo_type in self.val:
338 return True
362 return True
339 else:
363 else:
340 log.warning('Current view is not supported for repo type:%s',
364 log.warning('Current view is not supported for repo type:%s',
341 rhodecode_db_repo.repo_type)
365 rhodecode_db_repo.repo_type)
342 #
366 #
343 # h.flash(h.literal(
367 # h.flash(h.literal(
344 # _('Action not supported for %s.' % rhodecode_repo.alias)),
368 # _('Action not supported for %s.' % rhodecode_repo.alias)),
345 # category='warning')
369 # category='warning')
346 # return redirect(
370 # return redirect(
347 # route_path('repo_summary', repo_name=cls.rhodecode_db_repo.repo_name))
371 # route_path('repo_summary', repo_name=cls.rhodecode_db_repo.repo_name))
348
372
349 return False
373 return False
350
374
351
375
352 class RepoGroupRoutePredicate(object):
376 class RepoGroupRoutePredicate(object):
353 def __init__(self, val, config):
377 def __init__(self, val, config):
354 self.val = val
378 self.val = val
355
379
356 def text(self):
380 def text(self):
357 return 'repo_group_route = %s' % self.val
381 return 'repo_group_route = %s' % self.val
358
382
359 phash = text
383 phash = text
360
384
361 def __call__(self, info, request):
385 def __call__(self, info, request):
362 if hasattr(request, 'vcs_call'):
386 if hasattr(request, 'vcs_call'):
363 # skip vcs calls
387 # skip vcs calls
364 return
388 return
365
389
366 repo_group_name = info['match']['repo_group_name']
390 repo_group_name = info['match']['repo_group_name']
367 repo_group_model = repo_group.RepoGroupModel()
391 repo_group_model = repo_group.RepoGroupModel()
368 by_name_match = repo_group_model.get_by_group_name(
392 by_name_match = repo_group_model.get_by_group_name(
369 repo_group_name, cache=True)
393 repo_group_name, cache=True)
370
394
371 if by_name_match:
395 if by_name_match:
372 # register this as request object we can re-use later
396 # register this as request object we can re-use later
373 request.db_repo_group = by_name_match
397 request.db_repo_group = by_name_match
374 return True
398 return True
375
399
376 return False
400 return False
377
401
378
402
379 def includeme(config):
403 def includeme(config):
380 config.add_route_predicate(
404 config.add_route_predicate(
381 'repo_route', RepoRoutePredicate)
405 'repo_route', RepoRoutePredicate)
382 config.add_route_predicate(
406 config.add_route_predicate(
383 'repo_accepted_types', RepoTypeRoutePredicate)
407 'repo_accepted_types', RepoTypeRoutePredicate)
384 config.add_route_predicate(
408 config.add_route_predicate(
385 'repo_group_route', RepoGroupRoutePredicate)
409 'repo_group_route', RepoGroupRoutePredicate)
@@ -1,744 +1,731 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Routes configuration
22 Routes configuration
23
23
24 The more specific and detailed routes should be defined first so they
24 The more specific and detailed routes should be defined first so they
25 may take precedent over the more generic routes. For more information
25 may take precedent over the more generic routes. For more information
26 refer to the routes manual at http://routes.groovie.org/docs/
26 refer to the routes manual at http://routes.groovie.org/docs/
27
27
28 IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py
28 IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py
29 and _route_name variable which uses some of stored naming here to do redirects.
29 and _route_name variable which uses some of stored naming here to do redirects.
30 """
30 """
31 import os
31 import os
32 import re
32 import re
33 from routes import Mapper
33 from routes import Mapper
34
34
35 # prefix for non repository related links needs to be prefixed with `/`
35 # prefix for non repository related links needs to be prefixed with `/`
36 ADMIN_PREFIX = '/_admin'
36 ADMIN_PREFIX = '/_admin'
37 STATIC_FILE_PREFIX = '/_static'
37 STATIC_FILE_PREFIX = '/_static'
38
38
39 # Default requirements for URL parts
39 # Default requirements for URL parts
40 URL_NAME_REQUIREMENTS = {
40 URL_NAME_REQUIREMENTS = {
41 # group name can have a slash in them, but they must not end with a slash
41 # group name can have a slash in them, but they must not end with a slash
42 'group_name': r'.*?[^/]',
42 'group_name': r'.*?[^/]',
43 'repo_group_name': r'.*?[^/]',
43 'repo_group_name': r'.*?[^/]',
44 # repo names can have a slash in them, but they must not end with a slash
44 # repo names can have a slash in them, but they must not end with a slash
45 'repo_name': r'.*?[^/]',
45 'repo_name': r'.*?[^/]',
46 # file path eats up everything at the end
46 # file path eats up everything at the end
47 'f_path': r'.*',
47 'f_path': r'.*',
48 # reference types
48 # reference types
49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
51 }
51 }
52
52
53
53
54 def add_route_requirements(route_path, requirements):
55 """
56 Adds regex requirements to pyramid routes using a mapping dict
57
58 >>> add_route_requirements('/{action}/{id}', {'id': r'\d+'})
59 '/{action}/{id:\d+}'
60
61 """
62 for key, regex in requirements.items():
63 route_path = route_path.replace('{%s}' % key, '{%s:%s}' % (key, regex))
64 return route_path
65
66
67 class JSRoutesMapper(Mapper):
54 class JSRoutesMapper(Mapper):
68 """
55 """
69 Wrapper for routes.Mapper to make pyroutes compatible url definitions
56 Wrapper for routes.Mapper to make pyroutes compatible url definitions
70 """
57 """
71 _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$')
58 _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$')
72 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
59 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
73 def __init__(self, *args, **kw):
60 def __init__(self, *args, **kw):
74 super(JSRoutesMapper, self).__init__(*args, **kw)
61 super(JSRoutesMapper, self).__init__(*args, **kw)
75 self._jsroutes = []
62 self._jsroutes = []
76
63
77 def connect(self, *args, **kw):
64 def connect(self, *args, **kw):
78 """
65 """
79 Wrapper for connect to take an extra argument jsroute=True
66 Wrapper for connect to take an extra argument jsroute=True
80
67
81 :param jsroute: boolean, if True will add the route to the pyroutes list
68 :param jsroute: boolean, if True will add the route to the pyroutes list
82 """
69 """
83 if kw.pop('jsroute', False):
70 if kw.pop('jsroute', False):
84 if not self._named_route_regex.match(args[0]):
71 if not self._named_route_regex.match(args[0]):
85 raise Exception('only named routes can be added to pyroutes')
72 raise Exception('only named routes can be added to pyroutes')
86 self._jsroutes.append(args[0])
73 self._jsroutes.append(args[0])
87
74
88 super(JSRoutesMapper, self).connect(*args, **kw)
75 super(JSRoutesMapper, self).connect(*args, **kw)
89
76
90 def _extract_route_information(self, route):
77 def _extract_route_information(self, route):
91 """
78 """
92 Convert a route into tuple(name, path, args), eg:
79 Convert a route into tuple(name, path, args), eg:
93 ('show_user', '/profile/%(username)s', ['username'])
80 ('show_user', '/profile/%(username)s', ['username'])
94 """
81 """
95 routepath = route.routepath
82 routepath = route.routepath
96 def replace(matchobj):
83 def replace(matchobj):
97 if matchobj.group(1):
84 if matchobj.group(1):
98 return "%%(%s)s" % matchobj.group(1).split(':')[0]
85 return "%%(%s)s" % matchobj.group(1).split(':')[0]
99 else:
86 else:
100 return "%%(%s)s" % matchobj.group(2)
87 return "%%(%s)s" % matchobj.group(2)
101
88
102 routepath = self._argument_prog.sub(replace, routepath)
89 routepath = self._argument_prog.sub(replace, routepath)
103 return (
90 return (
104 route.name,
91 route.name,
105 routepath,
92 routepath,
106 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
93 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
107 for arg in self._argument_prog.findall(route.routepath)]
94 for arg in self._argument_prog.findall(route.routepath)]
108 )
95 )
109
96
110 def jsroutes(self):
97 def jsroutes(self):
111 """
98 """
112 Return a list of pyroutes.js compatible routes
99 Return a list of pyroutes.js compatible routes
113 """
100 """
114 for route_name in self._jsroutes:
101 for route_name in self._jsroutes:
115 yield self._extract_route_information(self._routenames[route_name])
102 yield self._extract_route_information(self._routenames[route_name])
116
103
117
104
118 def make_map(config):
105 def make_map(config):
119 """Create, configure and return the routes Mapper"""
106 """Create, configure and return the routes Mapper"""
120 rmap = JSRoutesMapper(
107 rmap = JSRoutesMapper(
121 directory=config['pylons.paths']['controllers'],
108 directory=config['pylons.paths']['controllers'],
122 always_scan=config['debug'])
109 always_scan=config['debug'])
123 rmap.minimization = False
110 rmap.minimization = False
124 rmap.explicit = False
111 rmap.explicit = False
125
112
126 from rhodecode.lib.utils2 import str2bool
113 from rhodecode.lib.utils2 import str2bool
127 from rhodecode.model import repo, repo_group
114 from rhodecode.model import repo, repo_group
128
115
129 def check_repo(environ, match_dict):
116 def check_repo(environ, match_dict):
130 """
117 """
131 check for valid repository for proper 404 handling
118 check for valid repository for proper 404 handling
132
119
133 :param environ:
120 :param environ:
134 :param match_dict:
121 :param match_dict:
135 """
122 """
136 repo_name = match_dict.get('repo_name')
123 repo_name = match_dict.get('repo_name')
137
124
138 if match_dict.get('f_path'):
125 if match_dict.get('f_path'):
139 # fix for multiple initial slashes that causes errors
126 # fix for multiple initial slashes that causes errors
140 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
127 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
141 repo_model = repo.RepoModel()
128 repo_model = repo.RepoModel()
142 by_name_match = repo_model.get_by_repo_name(repo_name)
129 by_name_match = repo_model.get_by_repo_name(repo_name)
143 # if we match quickly from database, short circuit the operation,
130 # if we match quickly from database, short circuit the operation,
144 # and validate repo based on the type.
131 # and validate repo based on the type.
145 if by_name_match:
132 if by_name_match:
146 return True
133 return True
147
134
148 by_id_match = repo_model.get_repo_by_id(repo_name)
135 by_id_match = repo_model.get_repo_by_id(repo_name)
149 if by_id_match:
136 if by_id_match:
150 repo_name = by_id_match.repo_name
137 repo_name = by_id_match.repo_name
151 match_dict['repo_name'] = repo_name
138 match_dict['repo_name'] = repo_name
152 return True
139 return True
153
140
154 return False
141 return False
155
142
156 def check_group(environ, match_dict):
143 def check_group(environ, match_dict):
157 """
144 """
158 check for valid repository group path for proper 404 handling
145 check for valid repository group path for proper 404 handling
159
146
160 :param environ:
147 :param environ:
161 :param match_dict:
148 :param match_dict:
162 """
149 """
163 repo_group_name = match_dict.get('group_name')
150 repo_group_name = match_dict.get('group_name')
164 repo_group_model = repo_group.RepoGroupModel()
151 repo_group_model = repo_group.RepoGroupModel()
165 by_name_match = repo_group_model.get_by_group_name(repo_group_name)
152 by_name_match = repo_group_model.get_by_group_name(repo_group_name)
166 if by_name_match:
153 if by_name_match:
167 return True
154 return True
168
155
169 return False
156 return False
170
157
171 def check_user_group(environ, match_dict):
158 def check_user_group(environ, match_dict):
172 """
159 """
173 check for valid user group for proper 404 handling
160 check for valid user group for proper 404 handling
174
161
175 :param environ:
162 :param environ:
176 :param match_dict:
163 :param match_dict:
177 """
164 """
178 return True
165 return True
179
166
180 def check_int(environ, match_dict):
167 def check_int(environ, match_dict):
181 return match_dict.get('id').isdigit()
168 return match_dict.get('id').isdigit()
182
169
183
170
184 #==========================================================================
171 #==========================================================================
185 # CUSTOM ROUTES HERE
172 # CUSTOM ROUTES HERE
186 #==========================================================================
173 #==========================================================================
187
174
188 # ping and pylons error test
175 # ping and pylons error test
189 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
176 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
190 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
177 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
191
178
192 # ADMIN REPOSITORY ROUTES
179 # ADMIN REPOSITORY ROUTES
193 with rmap.submapper(path_prefix=ADMIN_PREFIX,
180 with rmap.submapper(path_prefix=ADMIN_PREFIX,
194 controller='admin/repos') as m:
181 controller='admin/repos') as m:
195 m.connect('repos', '/repos',
182 m.connect('repos', '/repos',
196 action='create', conditions={'method': ['POST']})
183 action='create', conditions={'method': ['POST']})
197 m.connect('repos', '/repos',
184 m.connect('repos', '/repos',
198 action='index', conditions={'method': ['GET']})
185 action='index', conditions={'method': ['GET']})
199 m.connect('new_repo', '/create_repository', jsroute=True,
186 m.connect('new_repo', '/create_repository', jsroute=True,
200 action='create_repository', conditions={'method': ['GET']})
187 action='create_repository', conditions={'method': ['GET']})
201 m.connect('delete_repo', '/repos/{repo_name}',
188 m.connect('delete_repo', '/repos/{repo_name}',
202 action='delete', conditions={'method': ['DELETE']},
189 action='delete', conditions={'method': ['DELETE']},
203 requirements=URL_NAME_REQUIREMENTS)
190 requirements=URL_NAME_REQUIREMENTS)
204 m.connect('repo', '/repos/{repo_name}',
191 m.connect('repo', '/repos/{repo_name}',
205 action='show', conditions={'method': ['GET'],
192 action='show', conditions={'method': ['GET'],
206 'function': check_repo},
193 'function': check_repo},
207 requirements=URL_NAME_REQUIREMENTS)
194 requirements=URL_NAME_REQUIREMENTS)
208
195
209 # ADMIN REPOSITORY GROUPS ROUTES
196 # ADMIN REPOSITORY GROUPS ROUTES
210 with rmap.submapper(path_prefix=ADMIN_PREFIX,
197 with rmap.submapper(path_prefix=ADMIN_PREFIX,
211 controller='admin/repo_groups') as m:
198 controller='admin/repo_groups') as m:
212 m.connect('repo_groups', '/repo_groups',
199 m.connect('repo_groups', '/repo_groups',
213 action='create', conditions={'method': ['POST']})
200 action='create', conditions={'method': ['POST']})
214 m.connect('repo_groups', '/repo_groups',
201 m.connect('repo_groups', '/repo_groups',
215 action='index', conditions={'method': ['GET']})
202 action='index', conditions={'method': ['GET']})
216 m.connect('new_repo_group', '/repo_groups/new',
203 m.connect('new_repo_group', '/repo_groups/new',
217 action='new', conditions={'method': ['GET']})
204 action='new', conditions={'method': ['GET']})
218 m.connect('update_repo_group', '/repo_groups/{group_name}',
205 m.connect('update_repo_group', '/repo_groups/{group_name}',
219 action='update', conditions={'method': ['PUT'],
206 action='update', conditions={'method': ['PUT'],
220 'function': check_group},
207 'function': check_group},
221 requirements=URL_NAME_REQUIREMENTS)
208 requirements=URL_NAME_REQUIREMENTS)
222
209
223 # EXTRAS REPO GROUP ROUTES
210 # EXTRAS REPO GROUP ROUTES
224 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
211 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
225 action='edit',
212 action='edit',
226 conditions={'method': ['GET'], 'function': check_group},
213 conditions={'method': ['GET'], 'function': check_group},
227 requirements=URL_NAME_REQUIREMENTS)
214 requirements=URL_NAME_REQUIREMENTS)
228 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
215 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
229 action='edit',
216 action='edit',
230 conditions={'method': ['PUT'], 'function': check_group},
217 conditions={'method': ['PUT'], 'function': check_group},
231 requirements=URL_NAME_REQUIREMENTS)
218 requirements=URL_NAME_REQUIREMENTS)
232
219
233 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
220 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
234 action='edit_repo_group_advanced',
221 action='edit_repo_group_advanced',
235 conditions={'method': ['GET'], 'function': check_group},
222 conditions={'method': ['GET'], 'function': check_group},
236 requirements=URL_NAME_REQUIREMENTS)
223 requirements=URL_NAME_REQUIREMENTS)
237 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
224 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
238 action='edit_repo_group_advanced',
225 action='edit_repo_group_advanced',
239 conditions={'method': ['PUT'], 'function': check_group},
226 conditions={'method': ['PUT'], 'function': check_group},
240 requirements=URL_NAME_REQUIREMENTS)
227 requirements=URL_NAME_REQUIREMENTS)
241
228
242 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
229 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
243 action='edit_repo_group_perms',
230 action='edit_repo_group_perms',
244 conditions={'method': ['GET'], 'function': check_group},
231 conditions={'method': ['GET'], 'function': check_group},
245 requirements=URL_NAME_REQUIREMENTS)
232 requirements=URL_NAME_REQUIREMENTS)
246 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
233 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
247 action='update_perms',
234 action='update_perms',
248 conditions={'method': ['PUT'], 'function': check_group},
235 conditions={'method': ['PUT'], 'function': check_group},
249 requirements=URL_NAME_REQUIREMENTS)
236 requirements=URL_NAME_REQUIREMENTS)
250
237
251 m.connect('delete_repo_group', '/repo_groups/{group_name}',
238 m.connect('delete_repo_group', '/repo_groups/{group_name}',
252 action='delete', conditions={'method': ['DELETE'],
239 action='delete', conditions={'method': ['DELETE'],
253 'function': check_group},
240 'function': check_group},
254 requirements=URL_NAME_REQUIREMENTS)
241 requirements=URL_NAME_REQUIREMENTS)
255
242
256 # ADMIN USER ROUTES
243 # ADMIN USER ROUTES
257 with rmap.submapper(path_prefix=ADMIN_PREFIX,
244 with rmap.submapper(path_prefix=ADMIN_PREFIX,
258 controller='admin/users') as m:
245 controller='admin/users') as m:
259 m.connect('users', '/users',
246 m.connect('users', '/users',
260 action='create', conditions={'method': ['POST']})
247 action='create', conditions={'method': ['POST']})
261 m.connect('new_user', '/users/new',
248 m.connect('new_user', '/users/new',
262 action='new', conditions={'method': ['GET']})
249 action='new', conditions={'method': ['GET']})
263 m.connect('update_user', '/users/{user_id}',
250 m.connect('update_user', '/users/{user_id}',
264 action='update', conditions={'method': ['PUT']})
251 action='update', conditions={'method': ['PUT']})
265 m.connect('delete_user', '/users/{user_id}',
252 m.connect('delete_user', '/users/{user_id}',
266 action='delete', conditions={'method': ['DELETE']})
253 action='delete', conditions={'method': ['DELETE']})
267 m.connect('edit_user', '/users/{user_id}/edit',
254 m.connect('edit_user', '/users/{user_id}/edit',
268 action='edit', conditions={'method': ['GET']}, jsroute=True)
255 action='edit', conditions={'method': ['GET']}, jsroute=True)
269 m.connect('user', '/users/{user_id}',
256 m.connect('user', '/users/{user_id}',
270 action='show', conditions={'method': ['GET']})
257 action='show', conditions={'method': ['GET']})
271 m.connect('force_password_reset_user', '/users/{user_id}/password_reset',
258 m.connect('force_password_reset_user', '/users/{user_id}/password_reset',
272 action='reset_password', conditions={'method': ['POST']})
259 action='reset_password', conditions={'method': ['POST']})
273 m.connect('create_personal_repo_group', '/users/{user_id}/create_repo_group',
260 m.connect('create_personal_repo_group', '/users/{user_id}/create_repo_group',
274 action='create_personal_repo_group', conditions={'method': ['POST']})
261 action='create_personal_repo_group', conditions={'method': ['POST']})
275
262
276 # EXTRAS USER ROUTES
263 # EXTRAS USER ROUTES
277 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
264 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
278 action='edit_advanced', conditions={'method': ['GET']})
265 action='edit_advanced', conditions={'method': ['GET']})
279 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
266 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
280 action='update_advanced', conditions={'method': ['PUT']})
267 action='update_advanced', conditions={'method': ['PUT']})
281
268
282 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
269 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
283 action='edit_global_perms', conditions={'method': ['GET']})
270 action='edit_global_perms', conditions={'method': ['GET']})
284 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
271 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
285 action='update_global_perms', conditions={'method': ['PUT']})
272 action='update_global_perms', conditions={'method': ['PUT']})
286
273
287 m.connect('edit_user_perms_summary', '/users/{user_id}/edit/permissions_summary',
274 m.connect('edit_user_perms_summary', '/users/{user_id}/edit/permissions_summary',
288 action='edit_perms_summary', conditions={'method': ['GET']})
275 action='edit_perms_summary', conditions={'method': ['GET']})
289
276
290
277
291 # ADMIN USER GROUPS REST ROUTES
278 # ADMIN USER GROUPS REST ROUTES
292 with rmap.submapper(path_prefix=ADMIN_PREFIX,
279 with rmap.submapper(path_prefix=ADMIN_PREFIX,
293 controller='admin/user_groups') as m:
280 controller='admin/user_groups') as m:
294 m.connect('users_groups', '/user_groups',
281 m.connect('users_groups', '/user_groups',
295 action='create', conditions={'method': ['POST']})
282 action='create', conditions={'method': ['POST']})
296 m.connect('users_groups', '/user_groups',
283 m.connect('users_groups', '/user_groups',
297 action='index', conditions={'method': ['GET']})
284 action='index', conditions={'method': ['GET']})
298 m.connect('new_users_group', '/user_groups/new',
285 m.connect('new_users_group', '/user_groups/new',
299 action='new', conditions={'method': ['GET']})
286 action='new', conditions={'method': ['GET']})
300 m.connect('update_users_group', '/user_groups/{user_group_id}',
287 m.connect('update_users_group', '/user_groups/{user_group_id}',
301 action='update', conditions={'method': ['PUT']})
288 action='update', conditions={'method': ['PUT']})
302 m.connect('delete_users_group', '/user_groups/{user_group_id}',
289 m.connect('delete_users_group', '/user_groups/{user_group_id}',
303 action='delete', conditions={'method': ['DELETE']})
290 action='delete', conditions={'method': ['DELETE']})
304 m.connect('edit_users_group', '/user_groups/{user_group_id}/edit',
291 m.connect('edit_users_group', '/user_groups/{user_group_id}/edit',
305 action='edit', conditions={'method': ['GET']},
292 action='edit', conditions={'method': ['GET']},
306 function=check_user_group)
293 function=check_user_group)
307
294
308 # EXTRAS USER GROUP ROUTES
295 # EXTRAS USER GROUP ROUTES
309 m.connect('edit_user_group_global_perms',
296 m.connect('edit_user_group_global_perms',
310 '/user_groups/{user_group_id}/edit/global_permissions',
297 '/user_groups/{user_group_id}/edit/global_permissions',
311 action='edit_global_perms', conditions={'method': ['GET']})
298 action='edit_global_perms', conditions={'method': ['GET']})
312 m.connect('edit_user_group_global_perms',
299 m.connect('edit_user_group_global_perms',
313 '/user_groups/{user_group_id}/edit/global_permissions',
300 '/user_groups/{user_group_id}/edit/global_permissions',
314 action='update_global_perms', conditions={'method': ['PUT']})
301 action='update_global_perms', conditions={'method': ['PUT']})
315 m.connect('edit_user_group_perms_summary',
302 m.connect('edit_user_group_perms_summary',
316 '/user_groups/{user_group_id}/edit/permissions_summary',
303 '/user_groups/{user_group_id}/edit/permissions_summary',
317 action='edit_perms_summary', conditions={'method': ['GET']})
304 action='edit_perms_summary', conditions={'method': ['GET']})
318
305
319 m.connect('edit_user_group_perms',
306 m.connect('edit_user_group_perms',
320 '/user_groups/{user_group_id}/edit/permissions',
307 '/user_groups/{user_group_id}/edit/permissions',
321 action='edit_perms', conditions={'method': ['GET']})
308 action='edit_perms', conditions={'method': ['GET']})
322 m.connect('edit_user_group_perms',
309 m.connect('edit_user_group_perms',
323 '/user_groups/{user_group_id}/edit/permissions',
310 '/user_groups/{user_group_id}/edit/permissions',
324 action='update_perms', conditions={'method': ['PUT']})
311 action='update_perms', conditions={'method': ['PUT']})
325
312
326 m.connect('edit_user_group_advanced',
313 m.connect('edit_user_group_advanced',
327 '/user_groups/{user_group_id}/edit/advanced',
314 '/user_groups/{user_group_id}/edit/advanced',
328 action='edit_advanced', conditions={'method': ['GET']})
315 action='edit_advanced', conditions={'method': ['GET']})
329
316
330 m.connect('edit_user_group_advanced_sync',
317 m.connect('edit_user_group_advanced_sync',
331 '/user_groups/{user_group_id}/edit/advanced/sync',
318 '/user_groups/{user_group_id}/edit/advanced/sync',
332 action='edit_advanced_set_synchronization', conditions={'method': ['POST']})
319 action='edit_advanced_set_synchronization', conditions={'method': ['POST']})
333
320
334 m.connect('edit_user_group_members',
321 m.connect('edit_user_group_members',
335 '/user_groups/{user_group_id}/edit/members', jsroute=True,
322 '/user_groups/{user_group_id}/edit/members', jsroute=True,
336 action='user_group_members', conditions={'method': ['GET']})
323 action='user_group_members', conditions={'method': ['GET']})
337
324
338 # ADMIN PERMISSIONS ROUTES
325 # ADMIN PERMISSIONS ROUTES
339 with rmap.submapper(path_prefix=ADMIN_PREFIX,
326 with rmap.submapper(path_prefix=ADMIN_PREFIX,
340 controller='admin/permissions') as m:
327 controller='admin/permissions') as m:
341 m.connect('admin_permissions_application', '/permissions/application',
328 m.connect('admin_permissions_application', '/permissions/application',
342 action='permission_application_update', conditions={'method': ['POST']})
329 action='permission_application_update', conditions={'method': ['POST']})
343 m.connect('admin_permissions_application', '/permissions/application',
330 m.connect('admin_permissions_application', '/permissions/application',
344 action='permission_application', conditions={'method': ['GET']})
331 action='permission_application', conditions={'method': ['GET']})
345
332
346 m.connect('admin_permissions_global', '/permissions/global',
333 m.connect('admin_permissions_global', '/permissions/global',
347 action='permission_global_update', conditions={'method': ['POST']})
334 action='permission_global_update', conditions={'method': ['POST']})
348 m.connect('admin_permissions_global', '/permissions/global',
335 m.connect('admin_permissions_global', '/permissions/global',
349 action='permission_global', conditions={'method': ['GET']})
336 action='permission_global', conditions={'method': ['GET']})
350
337
351 m.connect('admin_permissions_object', '/permissions/object',
338 m.connect('admin_permissions_object', '/permissions/object',
352 action='permission_objects_update', conditions={'method': ['POST']})
339 action='permission_objects_update', conditions={'method': ['POST']})
353 m.connect('admin_permissions_object', '/permissions/object',
340 m.connect('admin_permissions_object', '/permissions/object',
354 action='permission_objects', conditions={'method': ['GET']})
341 action='permission_objects', conditions={'method': ['GET']})
355
342
356 m.connect('admin_permissions_ips', '/permissions/ips',
343 m.connect('admin_permissions_ips', '/permissions/ips',
357 action='permission_ips', conditions={'method': ['POST']})
344 action='permission_ips', conditions={'method': ['POST']})
358 m.connect('admin_permissions_ips', '/permissions/ips',
345 m.connect('admin_permissions_ips', '/permissions/ips',
359 action='permission_ips', conditions={'method': ['GET']})
346 action='permission_ips', conditions={'method': ['GET']})
360
347
361 m.connect('admin_permissions_overview', '/permissions/overview',
348 m.connect('admin_permissions_overview', '/permissions/overview',
362 action='permission_perms', conditions={'method': ['GET']})
349 action='permission_perms', conditions={'method': ['GET']})
363
350
364 # ADMIN DEFAULTS REST ROUTES
351 # ADMIN DEFAULTS REST ROUTES
365 with rmap.submapper(path_prefix=ADMIN_PREFIX,
352 with rmap.submapper(path_prefix=ADMIN_PREFIX,
366 controller='admin/defaults') as m:
353 controller='admin/defaults') as m:
367 m.connect('admin_defaults_repositories', '/defaults/repositories',
354 m.connect('admin_defaults_repositories', '/defaults/repositories',
368 action='update_repository_defaults', conditions={'method': ['POST']})
355 action='update_repository_defaults', conditions={'method': ['POST']})
369 m.connect('admin_defaults_repositories', '/defaults/repositories',
356 m.connect('admin_defaults_repositories', '/defaults/repositories',
370 action='index', conditions={'method': ['GET']})
357 action='index', conditions={'method': ['GET']})
371
358
372 # ADMIN SETTINGS ROUTES
359 # ADMIN SETTINGS ROUTES
373 with rmap.submapper(path_prefix=ADMIN_PREFIX,
360 with rmap.submapper(path_prefix=ADMIN_PREFIX,
374 controller='admin/settings') as m:
361 controller='admin/settings') as m:
375
362
376 # default
363 # default
377 m.connect('admin_settings', '/settings',
364 m.connect('admin_settings', '/settings',
378 action='settings_global_update',
365 action='settings_global_update',
379 conditions={'method': ['POST']})
366 conditions={'method': ['POST']})
380 m.connect('admin_settings', '/settings',
367 m.connect('admin_settings', '/settings',
381 action='settings_global', conditions={'method': ['GET']})
368 action='settings_global', conditions={'method': ['GET']})
382
369
383 m.connect('admin_settings_vcs', '/settings/vcs',
370 m.connect('admin_settings_vcs', '/settings/vcs',
384 action='settings_vcs_update',
371 action='settings_vcs_update',
385 conditions={'method': ['POST']})
372 conditions={'method': ['POST']})
386 m.connect('admin_settings_vcs', '/settings/vcs',
373 m.connect('admin_settings_vcs', '/settings/vcs',
387 action='settings_vcs',
374 action='settings_vcs',
388 conditions={'method': ['GET']})
375 conditions={'method': ['GET']})
389 m.connect('admin_settings_vcs', '/settings/vcs',
376 m.connect('admin_settings_vcs', '/settings/vcs',
390 action='delete_svn_pattern',
377 action='delete_svn_pattern',
391 conditions={'method': ['DELETE']})
378 conditions={'method': ['DELETE']})
392
379
393 m.connect('admin_settings_mapping', '/settings/mapping',
380 m.connect('admin_settings_mapping', '/settings/mapping',
394 action='settings_mapping_update',
381 action='settings_mapping_update',
395 conditions={'method': ['POST']})
382 conditions={'method': ['POST']})
396 m.connect('admin_settings_mapping', '/settings/mapping',
383 m.connect('admin_settings_mapping', '/settings/mapping',
397 action='settings_mapping', conditions={'method': ['GET']})
384 action='settings_mapping', conditions={'method': ['GET']})
398
385
399 m.connect('admin_settings_global', '/settings/global',
386 m.connect('admin_settings_global', '/settings/global',
400 action='settings_global_update',
387 action='settings_global_update',
401 conditions={'method': ['POST']})
388 conditions={'method': ['POST']})
402 m.connect('admin_settings_global', '/settings/global',
389 m.connect('admin_settings_global', '/settings/global',
403 action='settings_global', conditions={'method': ['GET']})
390 action='settings_global', conditions={'method': ['GET']})
404
391
405 m.connect('admin_settings_visual', '/settings/visual',
392 m.connect('admin_settings_visual', '/settings/visual',
406 action='settings_visual_update',
393 action='settings_visual_update',
407 conditions={'method': ['POST']})
394 conditions={'method': ['POST']})
408 m.connect('admin_settings_visual', '/settings/visual',
395 m.connect('admin_settings_visual', '/settings/visual',
409 action='settings_visual', conditions={'method': ['GET']})
396 action='settings_visual', conditions={'method': ['GET']})
410
397
411 m.connect('admin_settings_issuetracker',
398 m.connect('admin_settings_issuetracker',
412 '/settings/issue-tracker', action='settings_issuetracker',
399 '/settings/issue-tracker', action='settings_issuetracker',
413 conditions={'method': ['GET']})
400 conditions={'method': ['GET']})
414 m.connect('admin_settings_issuetracker_save',
401 m.connect('admin_settings_issuetracker_save',
415 '/settings/issue-tracker/save',
402 '/settings/issue-tracker/save',
416 action='settings_issuetracker_save',
403 action='settings_issuetracker_save',
417 conditions={'method': ['POST']})
404 conditions={'method': ['POST']})
418 m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
405 m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
419 action='settings_issuetracker_test',
406 action='settings_issuetracker_test',
420 conditions={'method': ['POST']})
407 conditions={'method': ['POST']})
421 m.connect('admin_issuetracker_delete',
408 m.connect('admin_issuetracker_delete',
422 '/settings/issue-tracker/delete',
409 '/settings/issue-tracker/delete',
423 action='settings_issuetracker_delete',
410 action='settings_issuetracker_delete',
424 conditions={'method': ['DELETE']})
411 conditions={'method': ['DELETE']})
425
412
426 m.connect('admin_settings_email', '/settings/email',
413 m.connect('admin_settings_email', '/settings/email',
427 action='settings_email_update',
414 action='settings_email_update',
428 conditions={'method': ['POST']})
415 conditions={'method': ['POST']})
429 m.connect('admin_settings_email', '/settings/email',
416 m.connect('admin_settings_email', '/settings/email',
430 action='settings_email', conditions={'method': ['GET']})
417 action='settings_email', conditions={'method': ['GET']})
431
418
432 m.connect('admin_settings_hooks', '/settings/hooks',
419 m.connect('admin_settings_hooks', '/settings/hooks',
433 action='settings_hooks_update',
420 action='settings_hooks_update',
434 conditions={'method': ['POST', 'DELETE']})
421 conditions={'method': ['POST', 'DELETE']})
435 m.connect('admin_settings_hooks', '/settings/hooks',
422 m.connect('admin_settings_hooks', '/settings/hooks',
436 action='settings_hooks', conditions={'method': ['GET']})
423 action='settings_hooks', conditions={'method': ['GET']})
437
424
438 m.connect('admin_settings_search', '/settings/search',
425 m.connect('admin_settings_search', '/settings/search',
439 action='settings_search', conditions={'method': ['GET']})
426 action='settings_search', conditions={'method': ['GET']})
440
427
441 m.connect('admin_settings_supervisor', '/settings/supervisor',
428 m.connect('admin_settings_supervisor', '/settings/supervisor',
442 action='settings_supervisor', conditions={'method': ['GET']})
429 action='settings_supervisor', conditions={'method': ['GET']})
443 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
430 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
444 action='settings_supervisor_log', conditions={'method': ['GET']})
431 action='settings_supervisor_log', conditions={'method': ['GET']})
445
432
446 m.connect('admin_settings_labs', '/settings/labs',
433 m.connect('admin_settings_labs', '/settings/labs',
447 action='settings_labs_update',
434 action='settings_labs_update',
448 conditions={'method': ['POST']})
435 conditions={'method': ['POST']})
449 m.connect('admin_settings_labs', '/settings/labs',
436 m.connect('admin_settings_labs', '/settings/labs',
450 action='settings_labs', conditions={'method': ['GET']})
437 action='settings_labs', conditions={'method': ['GET']})
451
438
452 # ADMIN MY ACCOUNT
439 # ADMIN MY ACCOUNT
453 with rmap.submapper(path_prefix=ADMIN_PREFIX,
440 with rmap.submapper(path_prefix=ADMIN_PREFIX,
454 controller='admin/my_account') as m:
441 controller='admin/my_account') as m:
455
442
456 # NOTE(marcink): this needs to be kept for password force flag to be
443 # NOTE(marcink): this needs to be kept for password force flag to be
457 # handled in pylons controllers, remove after full migration to pyramid
444 # handled in pylons controllers, remove after full migration to pyramid
458 m.connect('my_account_password', '/my_account/password',
445 m.connect('my_account_password', '/my_account/password',
459 action='my_account_password', conditions={'method': ['GET']})
446 action='my_account_password', conditions={'method': ['GET']})
460
447
461 # USER JOURNAL
448 # USER JOURNAL
462 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
449 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
463 controller='journal', action='index')
450 controller='journal', action='index')
464 rmap.connect('journal_rss', '%s/journal/rss' % (ADMIN_PREFIX,),
451 rmap.connect('journal_rss', '%s/journal/rss' % (ADMIN_PREFIX,),
465 controller='journal', action='journal_rss')
452 controller='journal', action='journal_rss')
466 rmap.connect('journal_atom', '%s/journal/atom' % (ADMIN_PREFIX,),
453 rmap.connect('journal_atom', '%s/journal/atom' % (ADMIN_PREFIX,),
467 controller='journal', action='journal_atom')
454 controller='journal', action='journal_atom')
468
455
469 rmap.connect('public_journal', '%s/public_journal' % (ADMIN_PREFIX,),
456 rmap.connect('public_journal', '%s/public_journal' % (ADMIN_PREFIX,),
470 controller='journal', action='public_journal')
457 controller='journal', action='public_journal')
471
458
472 rmap.connect('public_journal_rss', '%s/public_journal/rss' % (ADMIN_PREFIX,),
459 rmap.connect('public_journal_rss', '%s/public_journal/rss' % (ADMIN_PREFIX,),
473 controller='journal', action='public_journal_rss')
460 controller='journal', action='public_journal_rss')
474
461
475 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % (ADMIN_PREFIX,),
462 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % (ADMIN_PREFIX,),
476 controller='journal', action='public_journal_rss')
463 controller='journal', action='public_journal_rss')
477
464
478 rmap.connect('public_journal_atom',
465 rmap.connect('public_journal_atom',
479 '%s/public_journal/atom' % (ADMIN_PREFIX,), controller='journal',
466 '%s/public_journal/atom' % (ADMIN_PREFIX,), controller='journal',
480 action='public_journal_atom')
467 action='public_journal_atom')
481
468
482 rmap.connect('public_journal_atom_old',
469 rmap.connect('public_journal_atom_old',
483 '%s/public_journal_atom' % (ADMIN_PREFIX,), controller='journal',
470 '%s/public_journal_atom' % (ADMIN_PREFIX,), controller='journal',
484 action='public_journal_atom')
471 action='public_journal_atom')
485
472
486 rmap.connect('toggle_following', '%s/toggle_following' % (ADMIN_PREFIX,),
473 rmap.connect('toggle_following', '%s/toggle_following' % (ADMIN_PREFIX,),
487 controller='journal', action='toggle_following', jsroute=True,
474 controller='journal', action='toggle_following', jsroute=True,
488 conditions={'method': ['POST']})
475 conditions={'method': ['POST']})
489
476
490 #==========================================================================
477 #==========================================================================
491 # REPOSITORY ROUTES
478 # REPOSITORY ROUTES
492 #==========================================================================
479 #==========================================================================
493
480
494 rmap.connect('repo_creating_home', '/{repo_name}/repo_creating',
481 rmap.connect('repo_creating_home', '/{repo_name}/repo_creating',
495 controller='admin/repos', action='repo_creating',
482 controller='admin/repos', action='repo_creating',
496 requirements=URL_NAME_REQUIREMENTS)
483 requirements=URL_NAME_REQUIREMENTS)
497 rmap.connect('repo_check_home', '/{repo_name}/crepo_check',
484 rmap.connect('repo_check_home', '/{repo_name}/crepo_check',
498 controller='admin/repos', action='repo_check',
485 controller='admin/repos', action='repo_check',
499 requirements=URL_NAME_REQUIREMENTS)
486 requirements=URL_NAME_REQUIREMENTS)
500
487
501 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
488 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
502 controller='changeset', revision='tip',
489 controller='changeset', revision='tip',
503 conditions={'function': check_repo},
490 conditions={'function': check_repo},
504 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
491 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
505 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
492 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
506 controller='changeset', revision='tip', action='changeset_children',
493 controller='changeset', revision='tip', action='changeset_children',
507 conditions={'function': check_repo},
494 conditions={'function': check_repo},
508 requirements=URL_NAME_REQUIREMENTS)
495 requirements=URL_NAME_REQUIREMENTS)
509 rmap.connect('changeset_parents', '/{repo_name}/changeset_parents/{revision}',
496 rmap.connect('changeset_parents', '/{repo_name}/changeset_parents/{revision}',
510 controller='changeset', revision='tip', action='changeset_parents',
497 controller='changeset', revision='tip', action='changeset_parents',
511 conditions={'function': check_repo},
498 conditions={'function': check_repo},
512 requirements=URL_NAME_REQUIREMENTS)
499 requirements=URL_NAME_REQUIREMENTS)
513
500
514 # repo edit options
501 # repo edit options
515 rmap.connect('edit_repo_fields', '/{repo_name}/settings/fields',
502 rmap.connect('edit_repo_fields', '/{repo_name}/settings/fields',
516 controller='admin/repos', action='edit_fields',
503 controller='admin/repos', action='edit_fields',
517 conditions={'method': ['GET'], 'function': check_repo},
504 conditions={'method': ['GET'], 'function': check_repo},
518 requirements=URL_NAME_REQUIREMENTS)
505 requirements=URL_NAME_REQUIREMENTS)
519 rmap.connect('create_repo_fields', '/{repo_name}/settings/fields/new',
506 rmap.connect('create_repo_fields', '/{repo_name}/settings/fields/new',
520 controller='admin/repos', action='create_repo_field',
507 controller='admin/repos', action='create_repo_field',
521 conditions={'method': ['PUT'], 'function': check_repo},
508 conditions={'method': ['PUT'], 'function': check_repo},
522 requirements=URL_NAME_REQUIREMENTS)
509 requirements=URL_NAME_REQUIREMENTS)
523 rmap.connect('delete_repo_fields', '/{repo_name}/settings/fields/{field_id}',
510 rmap.connect('delete_repo_fields', '/{repo_name}/settings/fields/{field_id}',
524 controller='admin/repos', action='delete_repo_field',
511 controller='admin/repos', action='delete_repo_field',
525 conditions={'method': ['DELETE'], 'function': check_repo},
512 conditions={'method': ['DELETE'], 'function': check_repo},
526 requirements=URL_NAME_REQUIREMENTS)
513 requirements=URL_NAME_REQUIREMENTS)
527
514
528 rmap.connect('toggle_locking', '/{repo_name}/settings/advanced/locking_toggle',
515 rmap.connect('toggle_locking', '/{repo_name}/settings/advanced/locking_toggle',
529 controller='admin/repos', action='toggle_locking',
516 controller='admin/repos', action='toggle_locking',
530 conditions={'method': ['GET'], 'function': check_repo},
517 conditions={'method': ['GET'], 'function': check_repo},
531 requirements=URL_NAME_REQUIREMENTS)
518 requirements=URL_NAME_REQUIREMENTS)
532
519
533 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
520 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
534 controller='admin/repos', action='edit_remote_form',
521 controller='admin/repos', action='edit_remote_form',
535 conditions={'method': ['GET'], 'function': check_repo},
522 conditions={'method': ['GET'], 'function': check_repo},
536 requirements=URL_NAME_REQUIREMENTS)
523 requirements=URL_NAME_REQUIREMENTS)
537 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
524 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
538 controller='admin/repos', action='edit_remote',
525 controller='admin/repos', action='edit_remote',
539 conditions={'method': ['PUT'], 'function': check_repo},
526 conditions={'method': ['PUT'], 'function': check_repo},
540 requirements=URL_NAME_REQUIREMENTS)
527 requirements=URL_NAME_REQUIREMENTS)
541
528
542 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
529 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
543 controller='admin/repos', action='edit_statistics_form',
530 controller='admin/repos', action='edit_statistics_form',
544 conditions={'method': ['GET'], 'function': check_repo},
531 conditions={'method': ['GET'], 'function': check_repo},
545 requirements=URL_NAME_REQUIREMENTS)
532 requirements=URL_NAME_REQUIREMENTS)
546 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
533 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
547 controller='admin/repos', action='edit_statistics',
534 controller='admin/repos', action='edit_statistics',
548 conditions={'method': ['PUT'], 'function': check_repo},
535 conditions={'method': ['PUT'], 'function': check_repo},
549 requirements=URL_NAME_REQUIREMENTS)
536 requirements=URL_NAME_REQUIREMENTS)
550 rmap.connect('repo_settings_issuetracker',
537 rmap.connect('repo_settings_issuetracker',
551 '/{repo_name}/settings/issue-tracker',
538 '/{repo_name}/settings/issue-tracker',
552 controller='admin/repos', action='repo_issuetracker',
539 controller='admin/repos', action='repo_issuetracker',
553 conditions={'method': ['GET'], 'function': check_repo},
540 conditions={'method': ['GET'], 'function': check_repo},
554 requirements=URL_NAME_REQUIREMENTS)
541 requirements=URL_NAME_REQUIREMENTS)
555 rmap.connect('repo_issuetracker_test',
542 rmap.connect('repo_issuetracker_test',
556 '/{repo_name}/settings/issue-tracker/test',
543 '/{repo_name}/settings/issue-tracker/test',
557 controller='admin/repos', action='repo_issuetracker_test',
544 controller='admin/repos', action='repo_issuetracker_test',
558 conditions={'method': ['POST'], 'function': check_repo},
545 conditions={'method': ['POST'], 'function': check_repo},
559 requirements=URL_NAME_REQUIREMENTS)
546 requirements=URL_NAME_REQUIREMENTS)
560 rmap.connect('repo_issuetracker_delete',
547 rmap.connect('repo_issuetracker_delete',
561 '/{repo_name}/settings/issue-tracker/delete',
548 '/{repo_name}/settings/issue-tracker/delete',
562 controller='admin/repos', action='repo_issuetracker_delete',
549 controller='admin/repos', action='repo_issuetracker_delete',
563 conditions={'method': ['DELETE'], 'function': check_repo},
550 conditions={'method': ['DELETE'], 'function': check_repo},
564 requirements=URL_NAME_REQUIREMENTS)
551 requirements=URL_NAME_REQUIREMENTS)
565 rmap.connect('repo_issuetracker_save',
552 rmap.connect('repo_issuetracker_save',
566 '/{repo_name}/settings/issue-tracker/save',
553 '/{repo_name}/settings/issue-tracker/save',
567 controller='admin/repos', action='repo_issuetracker_save',
554 controller='admin/repos', action='repo_issuetracker_save',
568 conditions={'method': ['POST'], 'function': check_repo},
555 conditions={'method': ['POST'], 'function': check_repo},
569 requirements=URL_NAME_REQUIREMENTS)
556 requirements=URL_NAME_REQUIREMENTS)
570 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
557 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
571 controller='admin/repos', action='repo_settings_vcs_update',
558 controller='admin/repos', action='repo_settings_vcs_update',
572 conditions={'method': ['POST'], 'function': check_repo},
559 conditions={'method': ['POST'], 'function': check_repo},
573 requirements=URL_NAME_REQUIREMENTS)
560 requirements=URL_NAME_REQUIREMENTS)
574 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
561 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
575 controller='admin/repos', action='repo_settings_vcs',
562 controller='admin/repos', action='repo_settings_vcs',
576 conditions={'method': ['GET'], 'function': check_repo},
563 conditions={'method': ['GET'], 'function': check_repo},
577 requirements=URL_NAME_REQUIREMENTS)
564 requirements=URL_NAME_REQUIREMENTS)
578 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
565 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
579 controller='admin/repos', action='repo_delete_svn_pattern',
566 controller='admin/repos', action='repo_delete_svn_pattern',
580 conditions={'method': ['DELETE'], 'function': check_repo},
567 conditions={'method': ['DELETE'], 'function': check_repo},
581 requirements=URL_NAME_REQUIREMENTS)
568 requirements=URL_NAME_REQUIREMENTS)
582 rmap.connect('repo_pullrequest_settings', '/{repo_name}/settings/pullrequest',
569 rmap.connect('repo_pullrequest_settings', '/{repo_name}/settings/pullrequest',
583 controller='admin/repos', action='repo_settings_pullrequest',
570 controller='admin/repos', action='repo_settings_pullrequest',
584 conditions={'method': ['GET', 'POST'], 'function': check_repo},
571 conditions={'method': ['GET', 'POST'], 'function': check_repo},
585 requirements=URL_NAME_REQUIREMENTS)
572 requirements=URL_NAME_REQUIREMENTS)
586
573
587 # still working url for backward compat.
574 # still working url for backward compat.
588 rmap.connect('raw_changeset_home_depraced',
575 rmap.connect('raw_changeset_home_depraced',
589 '/{repo_name}/raw-changeset/{revision}',
576 '/{repo_name}/raw-changeset/{revision}',
590 controller='changeset', action='changeset_raw',
577 controller='changeset', action='changeset_raw',
591 revision='tip', conditions={'function': check_repo},
578 revision='tip', conditions={'function': check_repo},
592 requirements=URL_NAME_REQUIREMENTS)
579 requirements=URL_NAME_REQUIREMENTS)
593
580
594 # new URLs
581 # new URLs
595 rmap.connect('changeset_raw_home',
582 rmap.connect('changeset_raw_home',
596 '/{repo_name}/changeset-diff/{revision}',
583 '/{repo_name}/changeset-diff/{revision}',
597 controller='changeset', action='changeset_raw',
584 controller='changeset', action='changeset_raw',
598 revision='tip', conditions={'function': check_repo},
585 revision='tip', conditions={'function': check_repo},
599 requirements=URL_NAME_REQUIREMENTS)
586 requirements=URL_NAME_REQUIREMENTS)
600
587
601 rmap.connect('changeset_patch_home',
588 rmap.connect('changeset_patch_home',
602 '/{repo_name}/changeset-patch/{revision}',
589 '/{repo_name}/changeset-patch/{revision}',
603 controller='changeset', action='changeset_patch',
590 controller='changeset', action='changeset_patch',
604 revision='tip', conditions={'function': check_repo},
591 revision='tip', conditions={'function': check_repo},
605 requirements=URL_NAME_REQUIREMENTS)
592 requirements=URL_NAME_REQUIREMENTS)
606
593
607 rmap.connect('changeset_download_home',
594 rmap.connect('changeset_download_home',
608 '/{repo_name}/changeset-download/{revision}',
595 '/{repo_name}/changeset-download/{revision}',
609 controller='changeset', action='changeset_download',
596 controller='changeset', action='changeset_download',
610 revision='tip', conditions={'function': check_repo},
597 revision='tip', conditions={'function': check_repo},
611 requirements=URL_NAME_REQUIREMENTS)
598 requirements=URL_NAME_REQUIREMENTS)
612
599
613 rmap.connect('changeset_comment',
600 rmap.connect('changeset_comment',
614 '/{repo_name}/changeset/{revision}/comment', jsroute=True,
601 '/{repo_name}/changeset/{revision}/comment', jsroute=True,
615 controller='changeset', revision='tip', action='comment',
602 controller='changeset', revision='tip', action='comment',
616 conditions={'function': check_repo},
603 conditions={'function': check_repo},
617 requirements=URL_NAME_REQUIREMENTS)
604 requirements=URL_NAME_REQUIREMENTS)
618
605
619 rmap.connect('changeset_comment_preview',
606 rmap.connect('changeset_comment_preview',
620 '/{repo_name}/changeset/comment/preview', jsroute=True,
607 '/{repo_name}/changeset/comment/preview', jsroute=True,
621 controller='changeset', action='preview_comment',
608 controller='changeset', action='preview_comment',
622 conditions={'function': check_repo, 'method': ['POST']},
609 conditions={'function': check_repo, 'method': ['POST']},
623 requirements=URL_NAME_REQUIREMENTS)
610 requirements=URL_NAME_REQUIREMENTS)
624
611
625 rmap.connect('changeset_comment_delete',
612 rmap.connect('changeset_comment_delete',
626 '/{repo_name}/changeset/comment/{comment_id}/delete',
613 '/{repo_name}/changeset/comment/{comment_id}/delete',
627 controller='changeset', action='delete_comment',
614 controller='changeset', action='delete_comment',
628 conditions={'function': check_repo, 'method': ['DELETE']},
615 conditions={'function': check_repo, 'method': ['DELETE']},
629 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
616 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
630
617
631 rmap.connect('changeset_info', '/{repo_name}/changeset_info/{revision}',
618 rmap.connect('changeset_info', '/{repo_name}/changeset_info/{revision}',
632 controller='changeset', action='changeset_info',
619 controller='changeset', action='changeset_info',
633 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
620 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
634
621
635 rmap.connect('compare_home',
622 rmap.connect('compare_home',
636 '/{repo_name}/compare',
623 '/{repo_name}/compare',
637 controller='compare', action='index',
624 controller='compare', action='index',
638 conditions={'function': check_repo},
625 conditions={'function': check_repo},
639 requirements=URL_NAME_REQUIREMENTS)
626 requirements=URL_NAME_REQUIREMENTS)
640
627
641 rmap.connect('compare_url',
628 rmap.connect('compare_url',
642 '/{repo_name}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}',
629 '/{repo_name}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}',
643 controller='compare', action='compare',
630 controller='compare', action='compare',
644 conditions={'function': check_repo},
631 conditions={'function': check_repo},
645 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
632 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
646
633
647 rmap.connect('pullrequest_home',
634 rmap.connect('pullrequest_home',
648 '/{repo_name}/pull-request/new', controller='pullrequests',
635 '/{repo_name}/pull-request/new', controller='pullrequests',
649 action='index', conditions={'function': check_repo,
636 action='index', conditions={'function': check_repo,
650 'method': ['GET']},
637 'method': ['GET']},
651 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
638 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
652
639
653 rmap.connect('pullrequest',
640 rmap.connect('pullrequest',
654 '/{repo_name}/pull-request/new', controller='pullrequests',
641 '/{repo_name}/pull-request/new', controller='pullrequests',
655 action='create', conditions={'function': check_repo,
642 action='create', conditions={'function': check_repo,
656 'method': ['POST']},
643 'method': ['POST']},
657 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
644 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
658
645
659 rmap.connect('pullrequest_repo_refs',
646 rmap.connect('pullrequest_repo_refs',
660 '/{repo_name}/pull-request/refs/{target_repo_name:.*?[^/]}',
647 '/{repo_name}/pull-request/refs/{target_repo_name:.*?[^/]}',
661 controller='pullrequests',
648 controller='pullrequests',
662 action='get_repo_refs',
649 action='get_repo_refs',
663 conditions={'function': check_repo, 'method': ['GET']},
650 conditions={'function': check_repo, 'method': ['GET']},
664 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
651 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
665
652
666 rmap.connect('pullrequest_repo_destinations',
653 rmap.connect('pullrequest_repo_destinations',
667 '/{repo_name}/pull-request/repo-destinations',
654 '/{repo_name}/pull-request/repo-destinations',
668 controller='pullrequests',
655 controller='pullrequests',
669 action='get_repo_destinations',
656 action='get_repo_destinations',
670 conditions={'function': check_repo, 'method': ['GET']},
657 conditions={'function': check_repo, 'method': ['GET']},
671 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
658 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
672
659
673 rmap.connect('pullrequest_show',
660 rmap.connect('pullrequest_show',
674 '/{repo_name}/pull-request/{pull_request_id}',
661 '/{repo_name}/pull-request/{pull_request_id}',
675 controller='pullrequests',
662 controller='pullrequests',
676 action='show', conditions={'function': check_repo,
663 action='show', conditions={'function': check_repo,
677 'method': ['GET']},
664 'method': ['GET']},
678 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
665 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
679
666
680 rmap.connect('pullrequest_update',
667 rmap.connect('pullrequest_update',
681 '/{repo_name}/pull-request/{pull_request_id}',
668 '/{repo_name}/pull-request/{pull_request_id}',
682 controller='pullrequests',
669 controller='pullrequests',
683 action='update', conditions={'function': check_repo,
670 action='update', conditions={'function': check_repo,
684 'method': ['PUT']},
671 'method': ['PUT']},
685 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
672 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
686
673
687 rmap.connect('pullrequest_merge',
674 rmap.connect('pullrequest_merge',
688 '/{repo_name}/pull-request/{pull_request_id}',
675 '/{repo_name}/pull-request/{pull_request_id}',
689 controller='pullrequests',
676 controller='pullrequests',
690 action='merge', conditions={'function': check_repo,
677 action='merge', conditions={'function': check_repo,
691 'method': ['POST']},
678 'method': ['POST']},
692 requirements=URL_NAME_REQUIREMENTS)
679 requirements=URL_NAME_REQUIREMENTS)
693
680
694 rmap.connect('pullrequest_delete',
681 rmap.connect('pullrequest_delete',
695 '/{repo_name}/pull-request/{pull_request_id}',
682 '/{repo_name}/pull-request/{pull_request_id}',
696 controller='pullrequests',
683 controller='pullrequests',
697 action='delete', conditions={'function': check_repo,
684 action='delete', conditions={'function': check_repo,
698 'method': ['DELETE']},
685 'method': ['DELETE']},
699 requirements=URL_NAME_REQUIREMENTS)
686 requirements=URL_NAME_REQUIREMENTS)
700
687
701 rmap.connect('pullrequest_comment',
688 rmap.connect('pullrequest_comment',
702 '/{repo_name}/pull-request-comment/{pull_request_id}',
689 '/{repo_name}/pull-request-comment/{pull_request_id}',
703 controller='pullrequests',
690 controller='pullrequests',
704 action='comment', conditions={'function': check_repo,
691 action='comment', conditions={'function': check_repo,
705 'method': ['POST']},
692 'method': ['POST']},
706 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
693 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
707
694
708 rmap.connect('pullrequest_comment_delete',
695 rmap.connect('pullrequest_comment_delete',
709 '/{repo_name}/pull-request-comment/{comment_id}/delete',
696 '/{repo_name}/pull-request-comment/{comment_id}/delete',
710 controller='pullrequests', action='delete_comment',
697 controller='pullrequests', action='delete_comment',
711 conditions={'function': check_repo, 'method': ['DELETE']},
698 conditions={'function': check_repo, 'method': ['DELETE']},
712 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
699 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
713
700
714 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
701 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
715 controller='changelog', conditions={'function': check_repo},
702 controller='changelog', conditions={'function': check_repo},
716 requirements=URL_NAME_REQUIREMENTS)
703 requirements=URL_NAME_REQUIREMENTS)
717
704
718 rmap.connect('changelog_file_home',
705 rmap.connect('changelog_file_home',
719 '/{repo_name}/changelog/{revision}/{f_path}',
706 '/{repo_name}/changelog/{revision}/{f_path}',
720 controller='changelog', f_path=None,
707 controller='changelog', f_path=None,
721 conditions={'function': check_repo},
708 conditions={'function': check_repo},
722 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
709 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
723
710
724 rmap.connect('changelog_elements', '/{repo_name}/changelog_details',
711 rmap.connect('changelog_elements', '/{repo_name}/changelog_details',
725 controller='changelog', action='changelog_elements',
712 controller='changelog', action='changelog_elements',
726 conditions={'function': check_repo},
713 conditions={'function': check_repo},
727 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
714 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
728
715
729 rmap.connect('repo_fork_create_home', '/{repo_name}/fork',
716 rmap.connect('repo_fork_create_home', '/{repo_name}/fork',
730 controller='forks', action='fork_create',
717 controller='forks', action='fork_create',
731 conditions={'function': check_repo, 'method': ['POST']},
718 conditions={'function': check_repo, 'method': ['POST']},
732 requirements=URL_NAME_REQUIREMENTS)
719 requirements=URL_NAME_REQUIREMENTS)
733
720
734 rmap.connect('repo_fork_home', '/{repo_name}/fork',
721 rmap.connect('repo_fork_home', '/{repo_name}/fork',
735 controller='forks', action='fork',
722 controller='forks', action='fork',
736 conditions={'function': check_repo},
723 conditions={'function': check_repo},
737 requirements=URL_NAME_REQUIREMENTS)
724 requirements=URL_NAME_REQUIREMENTS)
738
725
739 rmap.connect('repo_forks_home', '/{repo_name}/forks',
726 rmap.connect('repo_forks_home', '/{repo_name}/forks',
740 controller='forks', action='forks',
727 controller='forks', action='forks',
741 conditions={'function': check_repo},
728 conditions={'function': check_repo},
742 requirements=URL_NAME_REQUIREMENTS)
729 requirements=URL_NAME_REQUIREMENTS)
743
730
744 return rmap
731 return rmap
@@ -1,238 +1,226 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2017 RhodeCode GmbH
3 # Copyright (C) 2012-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22
22
23 from rhodecode.apps._base import ADMIN_PREFIX, add_route_requirements
23 from rhodecode.model.db import Repository, Integration, RepoGroup
24 from rhodecode.model.db import Repository, Integration, RepoGroup
24 from rhodecode.config.routing import (
25 ADMIN_PREFIX, add_route_requirements, URL_NAME_REQUIREMENTS)
26 from rhodecode.integrations import integration_type_registry
25 from rhodecode.integrations import integration_type_registry
27
26
28 log = logging.getLogger(__name__)
27 log = logging.getLogger(__name__)
29
28
30
29
31 def includeme(config):
30 def includeme(config):
32
31
33 # global integrations
32 # global integrations
34
33
35 config.add_route('global_integrations_new',
34 config.add_route('global_integrations_new',
36 ADMIN_PREFIX + '/integrations/new')
35 ADMIN_PREFIX + '/integrations/new')
37 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
36 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
38 attr='new_integration',
37 attr='new_integration',
39 renderer='rhodecode:templates/admin/integrations/new.mako',
38 renderer='rhodecode:templates/admin/integrations/new.mako',
40 request_method='GET',
39 request_method='GET',
41 route_name='global_integrations_new')
40 route_name='global_integrations_new')
42
41
43 config.add_route('global_integrations_home',
42 config.add_route('global_integrations_home',
44 ADMIN_PREFIX + '/integrations')
43 ADMIN_PREFIX + '/integrations')
45 config.add_route('global_integrations_list',
44 config.add_route('global_integrations_list',
46 ADMIN_PREFIX + '/integrations/{integration}')
45 ADMIN_PREFIX + '/integrations/{integration}')
47 for route_name in ['global_integrations_home', 'global_integrations_list']:
46 for route_name in ['global_integrations_home', 'global_integrations_list']:
48 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
47 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
49 attr='index',
48 attr='index',
50 renderer='rhodecode:templates/admin/integrations/list.mako',
49 renderer='rhodecode:templates/admin/integrations/list.mako',
51 request_method='GET',
50 request_method='GET',
52 route_name=route_name)
51 route_name=route_name)
53
52
54 config.add_route('global_integrations_create',
53 config.add_route('global_integrations_create',
55 ADMIN_PREFIX + '/integrations/{integration}/new',
54 ADMIN_PREFIX + '/integrations/{integration}/new',
56 custom_predicates=(valid_integration,))
55 custom_predicates=(valid_integration,))
57 config.add_route('global_integrations_edit',
56 config.add_route('global_integrations_edit',
58 ADMIN_PREFIX + '/integrations/{integration}/{integration_id}',
57 ADMIN_PREFIX + '/integrations/{integration}/{integration_id}',
59 custom_predicates=(valid_integration,))
58 custom_predicates=(valid_integration,))
60
59
61
60
62 for route_name in ['global_integrations_create', 'global_integrations_edit']:
61 for route_name in ['global_integrations_create', 'global_integrations_edit']:
63 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
62 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
64 attr='settings_get',
63 attr='settings_get',
65 renderer='rhodecode:templates/admin/integrations/form.mako',
64 renderer='rhodecode:templates/admin/integrations/form.mako',
66 request_method='GET',
65 request_method='GET',
67 route_name=route_name)
66 route_name=route_name)
68 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
67 config.add_view('rhodecode.integrations.views.GlobalIntegrationsView',
69 attr='settings_post',
68 attr='settings_post',
70 renderer='rhodecode:templates/admin/integrations/form.mako',
69 renderer='rhodecode:templates/admin/integrations/form.mako',
71 request_method='POST',
70 request_method='POST',
72 route_name=route_name)
71 route_name=route_name)
73
72
74
73
75 # repo group integrations
74 # repo group integrations
76 config.add_route('repo_group_integrations_home',
75 config.add_route('repo_group_integrations_home',
77 add_route_requirements(
76 add_route_requirements(
78 '{repo_group_name}/settings/integrations',
77 '{repo_group_name}/settings/integrations',
79 URL_NAME_REQUIREMENTS
80 ),
78 ),
81 custom_predicates=(valid_repo_group,)
79 custom_predicates=(valid_repo_group,)
82 )
80 )
83 config.add_route('repo_group_integrations_list',
81 config.add_route('repo_group_integrations_list',
84 add_route_requirements(
82 add_route_requirements(
85 '{repo_group_name}/settings/integrations/{integration}',
83 '{repo_group_name}/settings/integrations/{integration}',
86 URL_NAME_REQUIREMENTS
87 ),
84 ),
88 custom_predicates=(valid_repo_group, valid_integration))
85 custom_predicates=(valid_repo_group, valid_integration))
89 for route_name in ['repo_group_integrations_home', 'repo_group_integrations_list']:
86 for route_name in ['repo_group_integrations_home', 'repo_group_integrations_list']:
90 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
87 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
91 attr='index',
88 attr='index',
92 renderer='rhodecode:templates/admin/integrations/list.mako',
89 renderer='rhodecode:templates/admin/integrations/list.mako',
93 request_method='GET',
90 request_method='GET',
94 route_name=route_name)
91 route_name=route_name)
95
92
96 config.add_route('repo_group_integrations_new',
93 config.add_route('repo_group_integrations_new',
97 add_route_requirements(
94 add_route_requirements(
98 '{repo_group_name}/settings/integrations/new',
95 '{repo_group_name}/settings/integrations/new',
99 URL_NAME_REQUIREMENTS
100 ),
96 ),
101 custom_predicates=(valid_repo_group,))
97 custom_predicates=(valid_repo_group,))
102 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
98 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
103 attr='new_integration',
99 attr='new_integration',
104 renderer='rhodecode:templates/admin/integrations/new.mako',
100 renderer='rhodecode:templates/admin/integrations/new.mako',
105 request_method='GET',
101 request_method='GET',
106 route_name='repo_group_integrations_new')
102 route_name='repo_group_integrations_new')
107
103
108 config.add_route('repo_group_integrations_create',
104 config.add_route('repo_group_integrations_create',
109 add_route_requirements(
105 add_route_requirements(
110 '{repo_group_name}/settings/integrations/{integration}/new',
106 '{repo_group_name}/settings/integrations/{integration}/new',
111 URL_NAME_REQUIREMENTS
112 ),
107 ),
113 custom_predicates=(valid_repo_group, valid_integration))
108 custom_predicates=(valid_repo_group, valid_integration))
114 config.add_route('repo_group_integrations_edit',
109 config.add_route('repo_group_integrations_edit',
115 add_route_requirements(
110 add_route_requirements(
116 '{repo_group_name}/settings/integrations/{integration}/{integration_id}',
111 '{repo_group_name}/settings/integrations/{integration}/{integration_id}',
117 URL_NAME_REQUIREMENTS
118 ),
112 ),
119 custom_predicates=(valid_repo_group, valid_integration))
113 custom_predicates=(valid_repo_group, valid_integration))
120 for route_name in ['repo_group_integrations_edit', 'repo_group_integrations_create']:
114 for route_name in ['repo_group_integrations_edit', 'repo_group_integrations_create']:
121 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
115 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
122 attr='settings_get',
116 attr='settings_get',
123 renderer='rhodecode:templates/admin/integrations/form.mako',
117 renderer='rhodecode:templates/admin/integrations/form.mako',
124 request_method='GET',
118 request_method='GET',
125 route_name=route_name)
119 route_name=route_name)
126 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
120 config.add_view('rhodecode.integrations.views.RepoGroupIntegrationsView',
127 attr='settings_post',
121 attr='settings_post',
128 renderer='rhodecode:templates/admin/integrations/form.mako',
122 renderer='rhodecode:templates/admin/integrations/form.mako',
129 request_method='POST',
123 request_method='POST',
130 route_name=route_name)
124 route_name=route_name)
131
125
132
126
133 # repo integrations
127 # repo integrations
134 config.add_route('repo_integrations_home',
128 config.add_route('repo_integrations_home',
135 add_route_requirements(
129 add_route_requirements(
136 '{repo_name}/settings/integrations',
130 '{repo_name}/settings/integrations',
137 URL_NAME_REQUIREMENTS
138 ),
131 ),
139 custom_predicates=(valid_repo,))
132 custom_predicates=(valid_repo,))
140 config.add_route('repo_integrations_list',
133 config.add_route('repo_integrations_list',
141 add_route_requirements(
134 add_route_requirements(
142 '{repo_name}/settings/integrations/{integration}',
135 '{repo_name}/settings/integrations/{integration}',
143 URL_NAME_REQUIREMENTS
144 ),
136 ),
145 custom_predicates=(valid_repo, valid_integration))
137 custom_predicates=(valid_repo, valid_integration))
146 for route_name in ['repo_integrations_home', 'repo_integrations_list']:
138 for route_name in ['repo_integrations_home', 'repo_integrations_list']:
147 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
139 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
148 attr='index',
140 attr='index',
149 request_method='GET',
141 request_method='GET',
150 renderer='rhodecode:templates/admin/integrations/list.mako',
142 renderer='rhodecode:templates/admin/integrations/list.mako',
151 route_name=route_name)
143 route_name=route_name)
152
144
153 config.add_route('repo_integrations_new',
145 config.add_route('repo_integrations_new',
154 add_route_requirements(
146 add_route_requirements(
155 '{repo_name}/settings/integrations/new',
147 '{repo_name}/settings/integrations/new',
156 URL_NAME_REQUIREMENTS
157 ),
148 ),
158 custom_predicates=(valid_repo,))
149 custom_predicates=(valid_repo,))
159 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
150 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
160 attr='new_integration',
151 attr='new_integration',
161 renderer='rhodecode:templates/admin/integrations/new.mako',
152 renderer='rhodecode:templates/admin/integrations/new.mako',
162 request_method='GET',
153 request_method='GET',
163 route_name='repo_integrations_new')
154 route_name='repo_integrations_new')
164
155
165 config.add_route('repo_integrations_create',
156 config.add_route('repo_integrations_create',
166 add_route_requirements(
157 add_route_requirements(
167 '{repo_name}/settings/integrations/{integration}/new',
158 '{repo_name}/settings/integrations/{integration}/new',
168 URL_NAME_REQUIREMENTS
169 ),
159 ),
170 custom_predicates=(valid_repo, valid_integration))
160 custom_predicates=(valid_repo, valid_integration))
171 config.add_route('repo_integrations_edit',
161 config.add_route('repo_integrations_edit',
172 add_route_requirements(
162 add_route_requirements(
173 '{repo_name}/settings/integrations/{integration}/{integration_id}',
163 '{repo_name}/settings/integrations/{integration}/{integration_id}',
174 URL_NAME_REQUIREMENTS
175 ),
164 ),
176 custom_predicates=(valid_repo, valid_integration))
165 custom_predicates=(valid_repo, valid_integration))
177 for route_name in ['repo_integrations_edit', 'repo_integrations_create']:
166 for route_name in ['repo_integrations_edit', 'repo_integrations_create']:
178 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
167 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
179 attr='settings_get',
168 attr='settings_get',
180 renderer='rhodecode:templates/admin/integrations/form.mako',
169 renderer='rhodecode:templates/admin/integrations/form.mako',
181 request_method='GET',
170 request_method='GET',
182 route_name=route_name)
171 route_name=route_name)
183 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
172 config.add_view('rhodecode.integrations.views.RepoIntegrationsView',
184 attr='settings_post',
173 attr='settings_post',
185 renderer='rhodecode:templates/admin/integrations/form.mako',
174 renderer='rhodecode:templates/admin/integrations/form.mako',
186 request_method='POST',
175 request_method='POST',
187 route_name=route_name)
176 route_name=route_name)
188
177
189
178
190 def valid_repo(info, request):
179 def valid_repo(info, request):
191 repo = Repository.get_by_repo_name(info['match']['repo_name'])
180 repo = Repository.get_by_repo_name(info['match']['repo_name'])
192 if repo:
181 if repo:
193 return True
182 return True
194
183
195
184
196 def valid_repo_group(info, request):
185 def valid_repo_group(info, request):
197 repo_group = RepoGroup.get_by_group_name(info['match']['repo_group_name'])
186 repo_group = RepoGroup.get_by_group_name(info['match']['repo_group_name'])
198 if repo_group:
187 if repo_group:
199 return True
188 return True
200 return False
189 return False
201
190
202
191
203 def valid_integration(info, request):
192 def valid_integration(info, request):
204 integration_type = info['match']['integration']
193 integration_type = info['match']['integration']
205 integration_id = info['match'].get('integration_id')
194 integration_id = info['match'].get('integration_id')
206 repo_name = info['match'].get('repo_name')
195 repo_name = info['match'].get('repo_name')
207 repo_group_name = info['match'].get('repo_group_name')
196 repo_group_name = info['match'].get('repo_group_name')
208
197
209 if integration_type not in integration_type_registry:
198 if integration_type not in integration_type_registry:
210 return False
199 return False
211
200
212 repo, repo_group = None, None
201 repo, repo_group = None, None
213 if repo_name:
202 if repo_name:
214 repo = Repository.get_by_repo_name(repo_name)
203 repo = Repository.get_by_repo_name(repo_name)
215 if not repo:
204 if not repo:
216 return False
205 return False
217
206
218 if repo_group_name:
207 if repo_group_name:
219 repo_group = RepoGroup.get_by_group_name(repo_group_name)
208 repo_group = RepoGroup.get_by_group_name(repo_group_name)
220 if not repo_group:
209 if not repo_group:
221 return False
210 return False
222
211
223 if repo_name and repo_group:
212 if repo_name and repo_group:
224 raise Exception('Either repo or repo_group can be set, not both')
213 raise Exception('Either repo or repo_group can be set, not both')
225
214
226
227 if integration_id:
215 if integration_id:
228 integration = Integration.get(integration_id)
216 integration = Integration.get(integration_id)
229 if not integration:
217 if not integration:
230 return False
218 return False
231 if integration.integration_type != integration_type:
219 if integration.integration_type != integration_type:
232 return False
220 return False
233 if repo and repo.repo_id != integration.repo_id:
221 if repo and repo.repo_id != integration.repo_id:
234 return False
222 return False
235 if repo_group and repo_group.group_id != integration.repo_group_id:
223 if repo_group and repo_group.group_id != integration.repo_group_id:
236 return False
224 return False
237
225
238 return True
226 return True
General Comments 0
You need to be logged in to leave comments. Login now