##// END OF EJS Templates
integrations: fixed view for integrations on repo.
marcink -
r3739:a3405fba new-ui
parent child Browse files
Show More
@@ -1,463 +1,464 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2019 RhodeCode GmbH
3 # Copyright (C) 2012-2019 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 deform
21 import deform
22 import logging
22 import logging
23 import peppercorn
23 import peppercorn
24 import webhelpers.paginate
24 import webhelpers.paginate
25
25
26 from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPNotFound
26 from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPNotFound
27
27
28 from rhodecode.integrations import integration_type_registry
28 from rhodecode.integrations import integration_type_registry
29 from rhodecode.apps._base import BaseAppView
29 from rhodecode.apps._base import BaseAppView
30 from rhodecode.apps._base.navigation import navigation_list
30 from rhodecode.apps._base.navigation import navigation_list
31 from rhodecode.lib.auth import (
31 from rhodecode.lib.auth import (
32 LoginRequired, CSRFRequired, HasPermissionAnyDecorator,
32 LoginRequired, CSRFRequired, HasPermissionAnyDecorator,
33 HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator)
33 HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator)
34 from rhodecode.lib.utils2 import safe_int
34 from rhodecode.lib.utils2 import safe_int
35 from rhodecode.lib import helpers as h
35 from rhodecode.lib import helpers as h
36 from rhodecode.model.db import Repository, RepoGroup, Session, Integration
36 from rhodecode.model.db import Repository, RepoGroup, Session, Integration
37 from rhodecode.model.scm import ScmModel
37 from rhodecode.model.scm import ScmModel
38 from rhodecode.model.integration import IntegrationModel
38 from rhodecode.model.integration import IntegrationModel
39 from rhodecode.model.validation_schema.schemas.integration_schema import (
39 from rhodecode.model.validation_schema.schemas.integration_schema import (
40 make_integration_schema, IntegrationScopeType)
40 make_integration_schema, IntegrationScopeType)
41
41
42 log = logging.getLogger(__name__)
42 log = logging.getLogger(__name__)
43
43
44
44
45 class IntegrationSettingsViewBase(BaseAppView):
45 class IntegrationSettingsViewBase(BaseAppView):
46 """
46 """
47 Base Integration settings view used by both repo / global settings
47 Base Integration settings view used by both repo / global settings
48 """
48 """
49
49
50 def __init__(self, context, request):
50 def __init__(self, context, request):
51 super(IntegrationSettingsViewBase, self).__init__(context, request)
51 super(IntegrationSettingsViewBase, self).__init__(context, request)
52 self._load_view_context()
52 self._load_view_context()
53
53
54 def _load_view_context(self):
54 def _load_view_context(self):
55 """
55 """
56 This avoids boilerplate for repo/global+list/edit+views/templates
56 This avoids boilerplate for repo/global+list/edit+views/templates
57 by doing all possible contexts at the same time however it should
57 by doing all possible contexts at the same time however it should
58 be split up into separate functions once more "contexts" exist
58 be split up into separate functions once more "contexts" exist
59 """
59 """
60
60
61 self.IntegrationType = None
61 self.IntegrationType = None
62 self.repo = None
62 self.repo = None
63 self.repo_group = None
63 self.repo_group = None
64 self.integration = None
64 self.integration = None
65 self.integrations = {}
65 self.integrations = {}
66
66
67 request = self.request
67 request = self.request
68
68
69 if 'repo_name' in request.matchdict: # in repo settings context
69 if 'repo_name' in request.matchdict: # in repo settings context
70 repo_name = request.matchdict['repo_name']
70 repo_name = request.matchdict['repo_name']
71 self.repo = Repository.get_by_repo_name(repo_name)
71 self.repo = Repository.get_by_repo_name(repo_name)
72
72
73 if 'repo_group_name' in request.matchdict: # in group settings context
73 if 'repo_group_name' in request.matchdict: # in group settings context
74 repo_group_name = request.matchdict['repo_group_name']
74 repo_group_name = request.matchdict['repo_group_name']
75 self.repo_group = RepoGroup.get_by_group_name(repo_group_name)
75 self.repo_group = RepoGroup.get_by_group_name(repo_group_name)
76
76
77 if 'integration' in request.matchdict: # integration type context
77 if 'integration' in request.matchdict: # integration type context
78 integration_type = request.matchdict['integration']
78 integration_type = request.matchdict['integration']
79 if integration_type not in integration_type_registry:
79 if integration_type not in integration_type_registry:
80 raise HTTPNotFound()
80 raise HTTPNotFound()
81
81
82 self.IntegrationType = integration_type_registry[integration_type]
82 self.IntegrationType = integration_type_registry[integration_type]
83 if self.IntegrationType.is_dummy:
83 if self.IntegrationType.is_dummy:
84 raise HTTPNotFound()
84 raise HTTPNotFound()
85
85
86 if 'integration_id' in request.matchdict: # single integration context
86 if 'integration_id' in request.matchdict: # single integration context
87 integration_id = request.matchdict['integration_id']
87 integration_id = request.matchdict['integration_id']
88 self.integration = Integration.get(integration_id)
88 self.integration = Integration.get(integration_id)
89
89
90 # extra perms check just in case
90 # extra perms check just in case
91 if not self._has_perms_for_integration(self.integration):
91 if not self._has_perms_for_integration(self.integration):
92 raise HTTPForbidden()
92 raise HTTPForbidden()
93
93
94 self.settings = self.integration and self.integration.settings or {}
94 self.settings = self.integration and self.integration.settings or {}
95 self.admin_view = not (self.repo or self.repo_group)
95 self.admin_view = not (self.repo or self.repo_group)
96
96
97 def _has_perms_for_integration(self, integration):
97 def _has_perms_for_integration(self, integration):
98 perms = self.request.user.permissions
98 perms = self.request.user.permissions
99
99
100 if 'hg.admin' in perms['global']:
100 if 'hg.admin' in perms['global']:
101 return True
101 return True
102
102
103 if integration.repo:
103 if integration.repo:
104 return perms['repositories'].get(
104 return perms['repositories'].get(
105 integration.repo.repo_name) == 'repository.admin'
105 integration.repo.repo_name) == 'repository.admin'
106
106
107 if integration.repo_group:
107 if integration.repo_group:
108 return perms['repositories_groups'].get(
108 return perms['repositories_groups'].get(
109 integration.repo_group.group_name) == 'group.admin'
109 integration.repo_group.group_name) == 'group.admin'
110
110
111 return False
111 return False
112
112
113 def _get_local_tmpl_context(self, include_app_defaults=True):
113 def _get_local_tmpl_context(self, include_app_defaults=True):
114 _ = self.request.translate
114 _ = self.request.translate
115 c = super(IntegrationSettingsViewBase, self)._get_local_tmpl_context(
115 c = super(IntegrationSettingsViewBase, self)._get_local_tmpl_context(
116 include_app_defaults=include_app_defaults)
116 include_app_defaults=include_app_defaults)
117 c.active = 'integrations'
117 c.active = 'integrations'
118
118
119 return c
119 return c
120
120
121 def _form_schema(self):
121 def _form_schema(self):
122 schema = make_integration_schema(IntegrationType=self.IntegrationType,
122 schema = make_integration_schema(IntegrationType=self.IntegrationType,
123 settings=self.settings)
123 settings=self.settings)
124
124
125 # returns a clone, important if mutating the schema later
125 # returns a clone, important if mutating the schema later
126 return schema.bind(
126 return schema.bind(
127 permissions=self.request.user.permissions,
127 permissions=self.request.user.permissions,
128 no_scope=not self.admin_view)
128 no_scope=not self.admin_view)
129
129
130 def _form_defaults(self):
130 def _form_defaults(self):
131 _ = self.request.translate
131 _ = self.request.translate
132 defaults = {}
132 defaults = {}
133
133
134 if self.integration:
134 if self.integration:
135 defaults['settings'] = self.integration.settings or {}
135 defaults['settings'] = self.integration.settings or {}
136 defaults['options'] = {
136 defaults['options'] = {
137 'name': self.integration.name,
137 'name': self.integration.name,
138 'enabled': self.integration.enabled,
138 'enabled': self.integration.enabled,
139 'scope': {
139 'scope': {
140 'repo': self.integration.repo,
140 'repo': self.integration.repo,
141 'repo_group': self.integration.repo_group,
141 'repo_group': self.integration.repo_group,
142 'child_repos_only': self.integration.child_repos_only,
142 'child_repos_only': self.integration.child_repos_only,
143 },
143 },
144 }
144 }
145 else:
145 else:
146 if self.repo:
146 if self.repo:
147 scope = _('{repo_name} repository').format(
147 scope = _('{repo_name} repository').format(
148 repo_name=self.repo.repo_name)
148 repo_name=self.repo.repo_name)
149 elif self.repo_group:
149 elif self.repo_group:
150 scope = _('{repo_group_name} repo group').format(
150 scope = _('{repo_group_name} repo group').format(
151 repo_group_name=self.repo_group.group_name)
151 repo_group_name=self.repo_group.group_name)
152 else:
152 else:
153 scope = _('Global')
153 scope = _('Global')
154
154
155 defaults['options'] = {
155 defaults['options'] = {
156 'enabled': True,
156 'enabled': True,
157 'name': _('{name} integration').format(
157 'name': _('{name} integration').format(
158 name=self.IntegrationType.display_name),
158 name=self.IntegrationType.display_name),
159 }
159 }
160 defaults['options']['scope'] = {
160 defaults['options']['scope'] = {
161 'repo': self.repo,
161 'repo': self.repo,
162 'repo_group': self.repo_group,
162 'repo_group': self.repo_group,
163 }
163 }
164
164
165 return defaults
165 return defaults
166
166
167 def _delete_integration(self, integration):
167 def _delete_integration(self, integration):
168 _ = self.request.translate
168 _ = self.request.translate
169 Session().delete(integration)
169 Session().delete(integration)
170 Session().commit()
170 Session().commit()
171 h.flash(
171 h.flash(
172 _('Integration {integration_name} deleted successfully.').format(
172 _('Integration {integration_name} deleted successfully.').format(
173 integration_name=integration.name),
173 integration_name=integration.name),
174 category='success')
174 category='success')
175
175
176 if self.repo:
176 if self.repo:
177 redirect_to = self.request.route_path(
177 redirect_to = self.request.route_path(
178 'repo_integrations_home', repo_name=self.repo.repo_name)
178 'repo_integrations_home', repo_name=self.repo.repo_name)
179 elif self.repo_group:
179 elif self.repo_group:
180 redirect_to = self.request.route_path(
180 redirect_to = self.request.route_path(
181 'repo_group_integrations_home',
181 'repo_group_integrations_home',
182 repo_group_name=self.repo_group.group_name)
182 repo_group_name=self.repo_group.group_name)
183 else:
183 else:
184 redirect_to = self.request.route_path('global_integrations_home')
184 redirect_to = self.request.route_path('global_integrations_home')
185 raise HTTPFound(redirect_to)
185 raise HTTPFound(redirect_to)
186
186
187 def _integration_list(self):
187 def _integration_list(self):
188 """ List integrations """
188 """ List integrations """
189
189
190 c = self.load_default_context()
190 c = self.load_default_context()
191 if self.repo:
191 if self.repo:
192 scope = self.repo
192 scope = self.repo
193 elif self.repo_group:
193 elif self.repo_group:
194 scope = self.repo_group
194 scope = self.repo_group
195 else:
195 else:
196 scope = 'all'
196 scope = 'all'
197
197
198 integrations = []
198 integrations = []
199
199
200 for IntType, integration in IntegrationModel().get_integrations(
200 for IntType, integration in IntegrationModel().get_integrations(
201 scope=scope, IntegrationType=self.IntegrationType):
201 scope=scope, IntegrationType=self.IntegrationType):
202
202
203 # extra permissions check *just in case*
203 # extra permissions check *just in case*
204 if not self._has_perms_for_integration(integration):
204 if not self._has_perms_for_integration(integration):
205 continue
205 continue
206
206
207 integrations.append((IntType, integration))
207 integrations.append((IntType, integration))
208
208
209 sort_arg = self.request.GET.get('sort', 'name:asc')
209 sort_arg = self.request.GET.get('sort', 'name:asc')
210 sort_dir = 'asc'
210 sort_dir = 'asc'
211 if ':' in sort_arg:
211 if ':' in sort_arg:
212 sort_field, sort_dir = sort_arg.split(':')
212 sort_field, sort_dir = sort_arg.split(':')
213 else:
213 else:
214 sort_field = sort_arg, 'asc'
214 sort_field = sort_arg, 'asc'
215
215
216 assert sort_field in ('name', 'integration_type', 'enabled', 'scope')
216 assert sort_field in ('name', 'integration_type', 'enabled', 'scope')
217
217
218 integrations.sort(
218 integrations.sort(
219 key=lambda x: getattr(x[1], sort_field),
219 key=lambda x: getattr(x[1], sort_field),
220 reverse=(sort_dir == 'desc'))
220 reverse=(sort_dir == 'desc'))
221
221
222 page_url = webhelpers.paginate.PageURL(
222 page_url = webhelpers.paginate.PageURL(
223 self.request.path, self.request.GET)
223 self.request.path, self.request.GET)
224 page = safe_int(self.request.GET.get('page', 1), 1)
224 page = safe_int(self.request.GET.get('page', 1), 1)
225
225
226 integrations = h.Page(
226 integrations = h.Page(
227 integrations, page=page, items_per_page=10, url=page_url)
227 integrations, page=page, items_per_page=10, url=page_url)
228
228
229 c.rev_sort_dir = sort_dir != 'desc' and 'desc' or 'asc'
229 c.rev_sort_dir = sort_dir != 'desc' and 'desc' or 'asc'
230
230
231 c.current_IntegrationType = self.IntegrationType
231 c.current_IntegrationType = self.IntegrationType
232 c.integrations_list = integrations
232 c.integrations_list = integrations
233 c.available_integrations = integration_type_registry
233 c.available_integrations = integration_type_registry
234
234
235 return self._get_template_context(c)
235 return self._get_template_context(c)
236
236
237 def _settings_get(self, defaults=None, form=None):
237 def _settings_get(self, defaults=None, form=None):
238 """
238 """
239 View that displays the integration settings as a form.
239 View that displays the integration settings as a form.
240 """
240 """
241 c = self.load_default_context()
241 c = self.load_default_context()
242
242
243 defaults = defaults or self._form_defaults()
243 defaults = defaults or self._form_defaults()
244 schema = self._form_schema()
244 schema = self._form_schema()
245
245
246 if self.integration:
246 if self.integration:
247 buttons = ('submit', 'delete')
247 buttons = ('submit', 'delete')
248 else:
248 else:
249 buttons = ('submit',)
249 buttons = ('submit',)
250
250
251 form = form or deform.Form(schema, appstruct=defaults, buttons=buttons)
251 form = form or deform.Form(schema, appstruct=defaults, buttons=buttons)
252
252
253 c.form = form
253 c.form = form
254 c.current_IntegrationType = self.IntegrationType
254 c.current_IntegrationType = self.IntegrationType
255 c.integration = self.integration
255 c.integration = self.integration
256
256
257 return self._get_template_context(c)
257 return self._get_template_context(c)
258
258
259 def _settings_post(self):
259 def _settings_post(self):
260 """
260 """
261 View that validates and stores the integration settings.
261 View that validates and stores the integration settings.
262 """
262 """
263 _ = self.request.translate
263 _ = self.request.translate
264
264
265 controls = self.request.POST.items()
265 controls = self.request.POST.items()
266 pstruct = peppercorn.parse(controls)
266 pstruct = peppercorn.parse(controls)
267
267
268 if self.integration and pstruct.get('delete'):
268 if self.integration and pstruct.get('delete'):
269 return self._delete_integration(self.integration)
269 return self._delete_integration(self.integration)
270
270
271 schema = self._form_schema()
271 schema = self._form_schema()
272
272
273 skip_settings_validation = False
273 skip_settings_validation = False
274 if self.integration and 'enabled' not in pstruct.get('options', {}):
274 if self.integration and 'enabled' not in pstruct.get('options', {}):
275 skip_settings_validation = True
275 skip_settings_validation = True
276 schema['settings'].validator = None
276 schema['settings'].validator = None
277 for field in schema['settings'].children:
277 for field in schema['settings'].children:
278 field.validator = None
278 field.validator = None
279 field.missing = ''
279 field.missing = ''
280
280
281 if self.integration:
281 if self.integration:
282 buttons = ('submit', 'delete')
282 buttons = ('submit', 'delete')
283 else:
283 else:
284 buttons = ('submit',)
284 buttons = ('submit',)
285
285
286 form = deform.Form(schema, buttons=buttons)
286 form = deform.Form(schema, buttons=buttons)
287
287
288 if not self.admin_view:
288 if not self.admin_view:
289 # scope is read only field in these cases, and has to be added
289 # scope is read only field in these cases, and has to be added
290 options = pstruct.setdefault('options', {})
290 options = pstruct.setdefault('options', {})
291 if 'scope' not in options:
291 if 'scope' not in options:
292 options['scope'] = IntegrationScopeType().serialize(None, {
292 options['scope'] = IntegrationScopeType().serialize(None, {
293 'repo': self.repo,
293 'repo': self.repo,
294 'repo_group': self.repo_group,
294 'repo_group': self.repo_group,
295 })
295 })
296
296
297 try:
297 try:
298 valid_data = form.validate_pstruct(pstruct)
298 valid_data = form.validate_pstruct(pstruct)
299 except deform.ValidationFailure as e:
299 except deform.ValidationFailure as e:
300 h.flash(
300 h.flash(
301 _('Errors exist when saving integration settings. '
301 _('Errors exist when saving integration settings. '
302 'Please check the form inputs.'),
302 'Please check the form inputs.'),
303 category='error')
303 category='error')
304 return self._settings_get(form=e)
304 return self._settings_get(form=e)
305
305
306 if not self.integration:
306 if not self.integration:
307 self.integration = Integration()
307 self.integration = Integration()
308 self.integration.integration_type = self.IntegrationType.key
308 self.integration.integration_type = self.IntegrationType.key
309 Session().add(self.integration)
309 Session().add(self.integration)
310
310
311 scope = valid_data['options']['scope']
311 scope = valid_data['options']['scope']
312
312
313 IntegrationModel().update_integration(self.integration,
313 IntegrationModel().update_integration(self.integration,
314 name=valid_data['options']['name'],
314 name=valid_data['options']['name'],
315 enabled=valid_data['options']['enabled'],
315 enabled=valid_data['options']['enabled'],
316 settings=valid_data['settings'],
316 settings=valid_data['settings'],
317 repo=scope['repo'],
317 repo=scope['repo'],
318 repo_group=scope['repo_group'],
318 repo_group=scope['repo_group'],
319 child_repos_only=scope['child_repos_only'],
319 child_repos_only=scope['child_repos_only'],
320 )
320 )
321
321
322 self.integration.settings = valid_data['settings']
322 self.integration.settings = valid_data['settings']
323 Session().commit()
323 Session().commit()
324 # Display success message and redirect.
324 # Display success message and redirect.
325 h.flash(
325 h.flash(
326 _('Integration {integration_name} updated successfully.').format(
326 _('Integration {integration_name} updated successfully.').format(
327 integration_name=self.IntegrationType.display_name),
327 integration_name=self.IntegrationType.display_name),
328 category='success')
328 category='success')
329
329
330 # if integration scope changes, we must redirect to the right place
330 # if integration scope changes, we must redirect to the right place
331 # keeping in mind if the original view was for /repo/ or /_admin/
331 # keeping in mind if the original view was for /repo/ or /_admin/
332 admin_view = not (self.repo or self.repo_group)
332 admin_view = not (self.repo or self.repo_group)
333
333
334 if self.integration.repo and not admin_view:
334 if self.integration.repo and not admin_view:
335 redirect_to = self.request.route_path(
335 redirect_to = self.request.route_path(
336 'repo_integrations_edit',
336 'repo_integrations_edit',
337 repo_name=self.integration.repo.repo_name,
337 repo_name=self.integration.repo.repo_name,
338 integration=self.integration.integration_type,
338 integration=self.integration.integration_type,
339 integration_id=self.integration.integration_id)
339 integration_id=self.integration.integration_id)
340 elif self.integration.repo_group and not admin_view:
340 elif self.integration.repo_group and not admin_view:
341 redirect_to = self.request.route_path(
341 redirect_to = self.request.route_path(
342 'repo_group_integrations_edit',
342 'repo_group_integrations_edit',
343 repo_group_name=self.integration.repo_group.group_name,
343 repo_group_name=self.integration.repo_group.group_name,
344 integration=self.integration.integration_type,
344 integration=self.integration.integration_type,
345 integration_id=self.integration.integration_id)
345 integration_id=self.integration.integration_id)
346 else:
346 else:
347 redirect_to = self.request.route_path(
347 redirect_to = self.request.route_path(
348 'global_integrations_edit',
348 'global_integrations_edit',
349 integration=self.integration.integration_type,
349 integration=self.integration.integration_type,
350 integration_id=self.integration.integration_id)
350 integration_id=self.integration.integration_id)
351
351
352 return HTTPFound(redirect_to)
352 return HTTPFound(redirect_to)
353
353
354 def _new_integration(self):
354 def _new_integration(self):
355 c = self.load_default_context()
355 c = self.load_default_context()
356 c.available_integrations = integration_type_registry
356 c.available_integrations = integration_type_registry
357 return self._get_template_context(c)
357 return self._get_template_context(c)
358
358
359 def load_default_context(self):
359 def load_default_context(self):
360 raise NotImplementedError()
360 raise NotImplementedError()
361
361
362
362
363 class GlobalIntegrationsView(IntegrationSettingsViewBase):
363 class GlobalIntegrationsView(IntegrationSettingsViewBase):
364 def load_default_context(self):
364 def load_default_context(self):
365 c = self._get_local_tmpl_context()
365 c = self._get_local_tmpl_context()
366 c.repo = self.repo
366 c.repo = self.repo
367 c.repo_group = self.repo_group
367 c.repo_group = self.repo_group
368 c.navlist = navigation_list(self.request)
368 c.navlist = navigation_list(self.request)
369
369
370 return c
370 return c
371
371
372 @LoginRequired()
372 @LoginRequired()
373 @HasPermissionAnyDecorator('hg.admin')
373 @HasPermissionAnyDecorator('hg.admin')
374 def integration_list(self):
374 def integration_list(self):
375 return self._integration_list()
375 return self._integration_list()
376
376
377 @LoginRequired()
377 @LoginRequired()
378 @HasPermissionAnyDecorator('hg.admin')
378 @HasPermissionAnyDecorator('hg.admin')
379 def settings_get(self):
379 def settings_get(self):
380 return self._settings_get()
380 return self._settings_get()
381
381
382 @LoginRequired()
382 @LoginRequired()
383 @HasPermissionAnyDecorator('hg.admin')
383 @HasPermissionAnyDecorator('hg.admin')
384 @CSRFRequired()
384 @CSRFRequired()
385 def settings_post(self):
385 def settings_post(self):
386 return self._settings_post()
386 return self._settings_post()
387
387
388 @LoginRequired()
388 @LoginRequired()
389 @HasPermissionAnyDecorator('hg.admin')
389 @HasPermissionAnyDecorator('hg.admin')
390 def new_integration(self):
390 def new_integration(self):
391 return self._new_integration()
391 return self._new_integration()
392
392
393
393
394 class RepoIntegrationsView(IntegrationSettingsViewBase):
394 class RepoIntegrationsView(IntegrationSettingsViewBase):
395 def load_default_context(self):
395 def load_default_context(self):
396 c = self._get_local_tmpl_context()
396 c = self._get_local_tmpl_context()
397
397
398 c.repo = self.repo
398 c.repo = self.repo
399 c.repo_group = self.repo_group
399 c.repo_group = self.repo_group
400
400
401 self.db_repo = self.repo
401 self.db_repo = self.repo
402 c.rhodecode_db_repo = self.repo
402 c.rhodecode_db_repo = self.repo
403 c.repo_name = self.db_repo.repo_name
403 c.repo_name = self.db_repo.repo_name
404 c.repository_pull_requests = ScmModel().get_pull_requests(self.repo)
404 c.repository_pull_requests = ScmModel().get_pull_requests(self.repo)
405
405 c.repository_is_user_following = ScmModel().is_following_repo(
406 c.repo_name, self._rhodecode_user.user_id)
406 c.has_origin_repo_read_perm = False
407 c.has_origin_repo_read_perm = False
407 if self.db_repo.fork:
408 if self.db_repo.fork:
408 c.has_origin_repo_read_perm = h.HasRepoPermissionAny(
409 c.has_origin_repo_read_perm = h.HasRepoPermissionAny(
409 'repository.write', 'repository.read', 'repository.admin')(
410 'repository.write', 'repository.read', 'repository.admin')(
410 self.db_repo.fork.repo_name, 'summary fork link')
411 self.db_repo.fork.repo_name, 'summary fork link')
411 return c
412 return c
412
413
413 @LoginRequired()
414 @LoginRequired()
414 @HasRepoPermissionAnyDecorator('repository.admin')
415 @HasRepoPermissionAnyDecorator('repository.admin')
415 def integration_list(self):
416 def integration_list(self):
416 return self._integration_list()
417 return self._integration_list()
417
418
418 @LoginRequired()
419 @LoginRequired()
419 @HasRepoPermissionAnyDecorator('repository.admin')
420 @HasRepoPermissionAnyDecorator('repository.admin')
420 def settings_get(self):
421 def settings_get(self):
421 return self._settings_get()
422 return self._settings_get()
422
423
423 @LoginRequired()
424 @LoginRequired()
424 @HasRepoPermissionAnyDecorator('repository.admin')
425 @HasRepoPermissionAnyDecorator('repository.admin')
425 @CSRFRequired()
426 @CSRFRequired()
426 def settings_post(self):
427 def settings_post(self):
427 return self._settings_post()
428 return self._settings_post()
428
429
429 @LoginRequired()
430 @LoginRequired()
430 @HasRepoPermissionAnyDecorator('repository.admin')
431 @HasRepoPermissionAnyDecorator('repository.admin')
431 def new_integration(self):
432 def new_integration(self):
432 return self._new_integration()
433 return self._new_integration()
433
434
434
435
435 class RepoGroupIntegrationsView(IntegrationSettingsViewBase):
436 class RepoGroupIntegrationsView(IntegrationSettingsViewBase):
436 def load_default_context(self):
437 def load_default_context(self):
437 c = self._get_local_tmpl_context()
438 c = self._get_local_tmpl_context()
438 c.repo = self.repo
439 c.repo = self.repo
439 c.repo_group = self.repo_group
440 c.repo_group = self.repo_group
440 c.navlist = navigation_list(self.request)
441 c.navlist = navigation_list(self.request)
441
442
442 return c
443 return c
443
444
444 @LoginRequired()
445 @LoginRequired()
445 @HasRepoGroupPermissionAnyDecorator('group.admin')
446 @HasRepoGroupPermissionAnyDecorator('group.admin')
446 def integration_list(self):
447 def integration_list(self):
447 return self._integration_list()
448 return self._integration_list()
448
449
449 @LoginRequired()
450 @LoginRequired()
450 @HasRepoGroupPermissionAnyDecorator('group.admin')
451 @HasRepoGroupPermissionAnyDecorator('group.admin')
451 def settings_get(self):
452 def settings_get(self):
452 return self._settings_get()
453 return self._settings_get()
453
454
454 @LoginRequired()
455 @LoginRequired()
455 @HasRepoGroupPermissionAnyDecorator('group.admin')
456 @HasRepoGroupPermissionAnyDecorator('group.admin')
456 @CSRFRequired()
457 @CSRFRequired()
457 def settings_post(self):
458 def settings_post(self):
458 return self._settings_post()
459 return self._settings_post()
459
460
460 @LoginRequired()
461 @LoginRequired()
461 @HasRepoGroupPermissionAnyDecorator('group.admin')
462 @HasRepoGroupPermissionAnyDecorator('group.admin')
462 def new_integration(self):
463 def new_integration(self):
463 return self._new_integration()
464 return self._new_integration()
General Comments 0
You need to be logged in to leave comments. Login now