##// END OF EJS Templates
permissions: flush all when running remap and rescan.
marcink -
r4428:61666194 default
parent child Browse files
Show More
@@ -1,782 +1,784 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 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 import logging
22 import logging
23 import collections
23 import collections
24
24
25 import datetime
25 import datetime
26 import formencode
26 import formencode
27 import formencode.htmlfill
27 import formencode.htmlfill
28
28
29 import rhodecode
29 import rhodecode
30 from pyramid.view import view_config
30 from pyramid.view import view_config
31 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
31 from pyramid.httpexceptions import HTTPFound, HTTPNotFound
32 from pyramid.renderers import render
32 from pyramid.renderers import render
33 from pyramid.response import Response
33 from pyramid.response import Response
34
34
35 from rhodecode.apps._base import BaseAppView
35 from rhodecode.apps._base import BaseAppView
36 from rhodecode.apps._base.navigation import navigation_list
36 from rhodecode.apps._base.navigation import navigation_list
37 from rhodecode.apps.svn_support.config_keys import generate_config
37 from rhodecode.apps.svn_support.config_keys import generate_config
38 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
39 from rhodecode.lib.auth import (
39 from rhodecode.lib.auth import (
40 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
40 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
41 from rhodecode.lib.celerylib import tasks, run_task
41 from rhodecode.lib.celerylib import tasks, run_task
42 from rhodecode.lib.utils import repo2db_mapper
42 from rhodecode.lib.utils import repo2db_mapper
43 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict
43 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict
44 from rhodecode.lib.index import searcher_from_config
44 from rhodecode.lib.index import searcher_from_config
45
45
46 from rhodecode.model.db import RhodeCodeUi, Repository
46 from rhodecode.model.db import RhodeCodeUi, Repository
47 from rhodecode.model.forms import (ApplicationSettingsForm,
47 from rhodecode.model.forms import (ApplicationSettingsForm,
48 ApplicationUiSettingsForm, ApplicationVisualisationForm,
48 ApplicationUiSettingsForm, ApplicationVisualisationForm,
49 LabsSettingsForm, IssueTrackerPatternsForm)
49 LabsSettingsForm, IssueTrackerPatternsForm)
50 from rhodecode.model.permission import PermissionModel
50 from rhodecode.model.repo_group import RepoGroupModel
51 from rhodecode.model.repo_group import RepoGroupModel
51
52
52 from rhodecode.model.scm import ScmModel
53 from rhodecode.model.scm import ScmModel
53 from rhodecode.model.notification import EmailNotificationModel
54 from rhodecode.model.notification import EmailNotificationModel
54 from rhodecode.model.meta import Session
55 from rhodecode.model.meta import Session
55 from rhodecode.model.settings import (
56 from rhodecode.model.settings import (
56 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
57 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
57 SettingsModel)
58 SettingsModel)
58
59
59
60
60 log = logging.getLogger(__name__)
61 log = logging.getLogger(__name__)
61
62
62
63
63 class AdminSettingsView(BaseAppView):
64 class AdminSettingsView(BaseAppView):
64
65
65 def load_default_context(self):
66 def load_default_context(self):
66 c = self._get_local_tmpl_context()
67 c = self._get_local_tmpl_context()
67 c.labs_active = str2bool(
68 c.labs_active = str2bool(
68 rhodecode.CONFIG.get('labs_settings_active', 'true'))
69 rhodecode.CONFIG.get('labs_settings_active', 'true'))
69 c.navlist = navigation_list(self.request)
70 c.navlist = navigation_list(self.request)
70
71
71 return c
72 return c
72
73
73 @classmethod
74 @classmethod
74 def _get_ui_settings(cls):
75 def _get_ui_settings(cls):
75 ret = RhodeCodeUi.query().all()
76 ret = RhodeCodeUi.query().all()
76
77
77 if not ret:
78 if not ret:
78 raise Exception('Could not get application ui settings !')
79 raise Exception('Could not get application ui settings !')
79 settings = {}
80 settings = {}
80 for each in ret:
81 for each in ret:
81 k = each.ui_key
82 k = each.ui_key
82 v = each.ui_value
83 v = each.ui_value
83 if k == '/':
84 if k == '/':
84 k = 'root_path'
85 k = 'root_path'
85
86
86 if k in ['push_ssl', 'publish', 'enabled']:
87 if k in ['push_ssl', 'publish', 'enabled']:
87 v = str2bool(v)
88 v = str2bool(v)
88
89
89 if k.find('.') != -1:
90 if k.find('.') != -1:
90 k = k.replace('.', '_')
91 k = k.replace('.', '_')
91
92
92 if each.ui_section in ['hooks', 'extensions']:
93 if each.ui_section in ['hooks', 'extensions']:
93 v = each.ui_active
94 v = each.ui_active
94
95
95 settings[each.ui_section + '_' + k] = v
96 settings[each.ui_section + '_' + k] = v
96 return settings
97 return settings
97
98
98 @classmethod
99 @classmethod
99 def _form_defaults(cls):
100 def _form_defaults(cls):
100 defaults = SettingsModel().get_all_settings()
101 defaults = SettingsModel().get_all_settings()
101 defaults.update(cls._get_ui_settings())
102 defaults.update(cls._get_ui_settings())
102
103
103 defaults.update({
104 defaults.update({
104 'new_svn_branch': '',
105 'new_svn_branch': '',
105 'new_svn_tag': '',
106 'new_svn_tag': '',
106 })
107 })
107 return defaults
108 return defaults
108
109
109 @LoginRequired()
110 @LoginRequired()
110 @HasPermissionAllDecorator('hg.admin')
111 @HasPermissionAllDecorator('hg.admin')
111 @view_config(
112 @view_config(
112 route_name='admin_settings_vcs', request_method='GET',
113 route_name='admin_settings_vcs', request_method='GET',
113 renderer='rhodecode:templates/admin/settings/settings.mako')
114 renderer='rhodecode:templates/admin/settings/settings.mako')
114 def settings_vcs(self):
115 def settings_vcs(self):
115 c = self.load_default_context()
116 c = self.load_default_context()
116 c.active = 'vcs'
117 c.active = 'vcs'
117 model = VcsSettingsModel()
118 model = VcsSettingsModel()
118 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
119 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
119 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
120 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
120
121
121 settings = self.request.registry.settings
122 settings = self.request.registry.settings
122 c.svn_proxy_generate_config = settings[generate_config]
123 c.svn_proxy_generate_config = settings[generate_config]
123
124
124 defaults = self._form_defaults()
125 defaults = self._form_defaults()
125
126
126 model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
127 model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
127
128
128 data = render('rhodecode:templates/admin/settings/settings.mako',
129 data = render('rhodecode:templates/admin/settings/settings.mako',
129 self._get_template_context(c), self.request)
130 self._get_template_context(c), self.request)
130 html = formencode.htmlfill.render(
131 html = formencode.htmlfill.render(
131 data,
132 data,
132 defaults=defaults,
133 defaults=defaults,
133 encoding="UTF-8",
134 encoding="UTF-8",
134 force_defaults=False
135 force_defaults=False
135 )
136 )
136 return Response(html)
137 return Response(html)
137
138
138 @LoginRequired()
139 @LoginRequired()
139 @HasPermissionAllDecorator('hg.admin')
140 @HasPermissionAllDecorator('hg.admin')
140 @CSRFRequired()
141 @CSRFRequired()
141 @view_config(
142 @view_config(
142 route_name='admin_settings_vcs_update', request_method='POST',
143 route_name='admin_settings_vcs_update', request_method='POST',
143 renderer='rhodecode:templates/admin/settings/settings.mako')
144 renderer='rhodecode:templates/admin/settings/settings.mako')
144 def settings_vcs_update(self):
145 def settings_vcs_update(self):
145 _ = self.request.translate
146 _ = self.request.translate
146 c = self.load_default_context()
147 c = self.load_default_context()
147 c.active = 'vcs'
148 c.active = 'vcs'
148
149
149 model = VcsSettingsModel()
150 model = VcsSettingsModel()
150 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
151 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
151 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
152 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
152
153
153 settings = self.request.registry.settings
154 settings = self.request.registry.settings
154 c.svn_proxy_generate_config = settings[generate_config]
155 c.svn_proxy_generate_config = settings[generate_config]
155
156
156 application_form = ApplicationUiSettingsForm(self.request.translate)()
157 application_form = ApplicationUiSettingsForm(self.request.translate)()
157
158
158 try:
159 try:
159 form_result = application_form.to_python(dict(self.request.POST))
160 form_result = application_form.to_python(dict(self.request.POST))
160 except formencode.Invalid as errors:
161 except formencode.Invalid as errors:
161 h.flash(
162 h.flash(
162 _("Some form inputs contain invalid data."),
163 _("Some form inputs contain invalid data."),
163 category='error')
164 category='error')
164 data = render('rhodecode:templates/admin/settings/settings.mako',
165 data = render('rhodecode:templates/admin/settings/settings.mako',
165 self._get_template_context(c), self.request)
166 self._get_template_context(c), self.request)
166 html = formencode.htmlfill.render(
167 html = formencode.htmlfill.render(
167 data,
168 data,
168 defaults=errors.value,
169 defaults=errors.value,
169 errors=errors.error_dict or {},
170 errors=errors.error_dict or {},
170 prefix_error=False,
171 prefix_error=False,
171 encoding="UTF-8",
172 encoding="UTF-8",
172 force_defaults=False
173 force_defaults=False
173 )
174 )
174 return Response(html)
175 return Response(html)
175
176
176 try:
177 try:
177 if c.visual.allow_repo_location_change:
178 if c.visual.allow_repo_location_change:
178 model.update_global_path_setting(form_result['paths_root_path'])
179 model.update_global_path_setting(form_result['paths_root_path'])
179
180
180 model.update_global_ssl_setting(form_result['web_push_ssl'])
181 model.update_global_ssl_setting(form_result['web_push_ssl'])
181 model.update_global_hook_settings(form_result)
182 model.update_global_hook_settings(form_result)
182
183
183 model.create_or_update_global_svn_settings(form_result)
184 model.create_or_update_global_svn_settings(form_result)
184 model.create_or_update_global_hg_settings(form_result)
185 model.create_or_update_global_hg_settings(form_result)
185 model.create_or_update_global_git_settings(form_result)
186 model.create_or_update_global_git_settings(form_result)
186 model.create_or_update_global_pr_settings(form_result)
187 model.create_or_update_global_pr_settings(form_result)
187 except Exception:
188 except Exception:
188 log.exception("Exception while updating settings")
189 log.exception("Exception while updating settings")
189 h.flash(_('Error occurred during updating '
190 h.flash(_('Error occurred during updating '
190 'application settings'), category='error')
191 'application settings'), category='error')
191 else:
192 else:
192 Session().commit()
193 Session().commit()
193 h.flash(_('Updated VCS settings'), category='success')
194 h.flash(_('Updated VCS settings'), category='success')
194 raise HTTPFound(h.route_path('admin_settings_vcs'))
195 raise HTTPFound(h.route_path('admin_settings_vcs'))
195
196
196 data = render('rhodecode:templates/admin/settings/settings.mako',
197 data = render('rhodecode:templates/admin/settings/settings.mako',
197 self._get_template_context(c), self.request)
198 self._get_template_context(c), self.request)
198 html = formencode.htmlfill.render(
199 html = formencode.htmlfill.render(
199 data,
200 data,
200 defaults=self._form_defaults(),
201 defaults=self._form_defaults(),
201 encoding="UTF-8",
202 encoding="UTF-8",
202 force_defaults=False
203 force_defaults=False
203 )
204 )
204 return Response(html)
205 return Response(html)
205
206
206 @LoginRequired()
207 @LoginRequired()
207 @HasPermissionAllDecorator('hg.admin')
208 @HasPermissionAllDecorator('hg.admin')
208 @CSRFRequired()
209 @CSRFRequired()
209 @view_config(
210 @view_config(
210 route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST',
211 route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST',
211 renderer='json_ext', xhr=True)
212 renderer='json_ext', xhr=True)
212 def settings_vcs_delete_svn_pattern(self):
213 def settings_vcs_delete_svn_pattern(self):
213 delete_pattern_id = self.request.POST.get('delete_svn_pattern')
214 delete_pattern_id = self.request.POST.get('delete_svn_pattern')
214 model = VcsSettingsModel()
215 model = VcsSettingsModel()
215 try:
216 try:
216 model.delete_global_svn_pattern(delete_pattern_id)
217 model.delete_global_svn_pattern(delete_pattern_id)
217 except SettingNotFound:
218 except SettingNotFound:
218 log.exception(
219 log.exception(
219 'Failed to delete svn_pattern with id %s', delete_pattern_id)
220 'Failed to delete svn_pattern with id %s', delete_pattern_id)
220 raise HTTPNotFound()
221 raise HTTPNotFound()
221
222
222 Session().commit()
223 Session().commit()
223 return True
224 return True
224
225
225 @LoginRequired()
226 @LoginRequired()
226 @HasPermissionAllDecorator('hg.admin')
227 @HasPermissionAllDecorator('hg.admin')
227 @view_config(
228 @view_config(
228 route_name='admin_settings_mapping', request_method='GET',
229 route_name='admin_settings_mapping', request_method='GET',
229 renderer='rhodecode:templates/admin/settings/settings.mako')
230 renderer='rhodecode:templates/admin/settings/settings.mako')
230 def settings_mapping(self):
231 def settings_mapping(self):
231 c = self.load_default_context()
232 c = self.load_default_context()
232 c.active = 'mapping'
233 c.active = 'mapping'
233
234
234 data = render('rhodecode:templates/admin/settings/settings.mako',
235 data = render('rhodecode:templates/admin/settings/settings.mako',
235 self._get_template_context(c), self.request)
236 self._get_template_context(c), self.request)
236 html = formencode.htmlfill.render(
237 html = formencode.htmlfill.render(
237 data,
238 data,
238 defaults=self._form_defaults(),
239 defaults=self._form_defaults(),
239 encoding="UTF-8",
240 encoding="UTF-8",
240 force_defaults=False
241 force_defaults=False
241 )
242 )
242 return Response(html)
243 return Response(html)
243
244
244 @LoginRequired()
245 @LoginRequired()
245 @HasPermissionAllDecorator('hg.admin')
246 @HasPermissionAllDecorator('hg.admin')
246 @CSRFRequired()
247 @CSRFRequired()
247 @view_config(
248 @view_config(
248 route_name='admin_settings_mapping_update', request_method='POST',
249 route_name='admin_settings_mapping_update', request_method='POST',
249 renderer='rhodecode:templates/admin/settings/settings.mako')
250 renderer='rhodecode:templates/admin/settings/settings.mako')
250 def settings_mapping_update(self):
251 def settings_mapping_update(self):
251 _ = self.request.translate
252 _ = self.request.translate
252 c = self.load_default_context()
253 c = self.load_default_context()
253 c.active = 'mapping'
254 c.active = 'mapping'
254 rm_obsolete = self.request.POST.get('destroy', False)
255 rm_obsolete = self.request.POST.get('destroy', False)
255 invalidate_cache = self.request.POST.get('invalidate', False)
256 invalidate_cache = self.request.POST.get('invalidate', False)
256 log.debug(
257 log.debug('rescanning repo location with destroy obsolete=%s', rm_obsolete)
257 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
258
258
259 if invalidate_cache:
259 if invalidate_cache:
260 log.debug('invalidating all repositories cache')
260 log.debug('invalidating all repositories cache')
261 for repo in Repository.get_all():
261 for repo in Repository.get_all():
262 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
262 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
263
263
264 filesystem_repos = ScmModel().repo_scan()
264 filesystem_repos = ScmModel().repo_scan()
265 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
265 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
266 PermissionModel().trigger_permission_flush()
267
266 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
268 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
267 h.flash(_('Repositories successfully '
269 h.flash(_('Repositories successfully '
268 'rescanned added: %s ; removed: %s') %
270 'rescanned added: %s ; removed: %s') %
269 (_repr(added), _repr(removed)),
271 (_repr(added), _repr(removed)),
270 category='success')
272 category='success')
271 raise HTTPFound(h.route_path('admin_settings_mapping'))
273 raise HTTPFound(h.route_path('admin_settings_mapping'))
272
274
273 @LoginRequired()
275 @LoginRequired()
274 @HasPermissionAllDecorator('hg.admin')
276 @HasPermissionAllDecorator('hg.admin')
275 @view_config(
277 @view_config(
276 route_name='admin_settings', request_method='GET',
278 route_name='admin_settings', request_method='GET',
277 renderer='rhodecode:templates/admin/settings/settings.mako')
279 renderer='rhodecode:templates/admin/settings/settings.mako')
278 @view_config(
280 @view_config(
279 route_name='admin_settings_global', request_method='GET',
281 route_name='admin_settings_global', request_method='GET',
280 renderer='rhodecode:templates/admin/settings/settings.mako')
282 renderer='rhodecode:templates/admin/settings/settings.mako')
281 def settings_global(self):
283 def settings_global(self):
282 c = self.load_default_context()
284 c = self.load_default_context()
283 c.active = 'global'
285 c.active = 'global'
284 c.personal_repo_group_default_pattern = RepoGroupModel()\
286 c.personal_repo_group_default_pattern = RepoGroupModel()\
285 .get_personal_group_name_pattern()
287 .get_personal_group_name_pattern()
286
288
287 data = render('rhodecode:templates/admin/settings/settings.mako',
289 data = render('rhodecode:templates/admin/settings/settings.mako',
288 self._get_template_context(c), self.request)
290 self._get_template_context(c), self.request)
289 html = formencode.htmlfill.render(
291 html = formencode.htmlfill.render(
290 data,
292 data,
291 defaults=self._form_defaults(),
293 defaults=self._form_defaults(),
292 encoding="UTF-8",
294 encoding="UTF-8",
293 force_defaults=False
295 force_defaults=False
294 )
296 )
295 return Response(html)
297 return Response(html)
296
298
297 @LoginRequired()
299 @LoginRequired()
298 @HasPermissionAllDecorator('hg.admin')
300 @HasPermissionAllDecorator('hg.admin')
299 @CSRFRequired()
301 @CSRFRequired()
300 @view_config(
302 @view_config(
301 route_name='admin_settings_update', request_method='POST',
303 route_name='admin_settings_update', request_method='POST',
302 renderer='rhodecode:templates/admin/settings/settings.mako')
304 renderer='rhodecode:templates/admin/settings/settings.mako')
303 @view_config(
305 @view_config(
304 route_name='admin_settings_global_update', request_method='POST',
306 route_name='admin_settings_global_update', request_method='POST',
305 renderer='rhodecode:templates/admin/settings/settings.mako')
307 renderer='rhodecode:templates/admin/settings/settings.mako')
306 def settings_global_update(self):
308 def settings_global_update(self):
307 _ = self.request.translate
309 _ = self.request.translate
308 c = self.load_default_context()
310 c = self.load_default_context()
309 c.active = 'global'
311 c.active = 'global'
310 c.personal_repo_group_default_pattern = RepoGroupModel()\
312 c.personal_repo_group_default_pattern = RepoGroupModel()\
311 .get_personal_group_name_pattern()
313 .get_personal_group_name_pattern()
312 application_form = ApplicationSettingsForm(self.request.translate)()
314 application_form = ApplicationSettingsForm(self.request.translate)()
313 try:
315 try:
314 form_result = application_form.to_python(dict(self.request.POST))
316 form_result = application_form.to_python(dict(self.request.POST))
315 except formencode.Invalid as errors:
317 except formencode.Invalid as errors:
316 h.flash(
318 h.flash(
317 _("Some form inputs contain invalid data."),
319 _("Some form inputs contain invalid data."),
318 category='error')
320 category='error')
319 data = render('rhodecode:templates/admin/settings/settings.mako',
321 data = render('rhodecode:templates/admin/settings/settings.mako',
320 self._get_template_context(c), self.request)
322 self._get_template_context(c), self.request)
321 html = formencode.htmlfill.render(
323 html = formencode.htmlfill.render(
322 data,
324 data,
323 defaults=errors.value,
325 defaults=errors.value,
324 errors=errors.error_dict or {},
326 errors=errors.error_dict or {},
325 prefix_error=False,
327 prefix_error=False,
326 encoding="UTF-8",
328 encoding="UTF-8",
327 force_defaults=False
329 force_defaults=False
328 )
330 )
329 return Response(html)
331 return Response(html)
330
332
331 settings = [
333 settings = [
332 ('title', 'rhodecode_title', 'unicode'),
334 ('title', 'rhodecode_title', 'unicode'),
333 ('realm', 'rhodecode_realm', 'unicode'),
335 ('realm', 'rhodecode_realm', 'unicode'),
334 ('pre_code', 'rhodecode_pre_code', 'unicode'),
336 ('pre_code', 'rhodecode_pre_code', 'unicode'),
335 ('post_code', 'rhodecode_post_code', 'unicode'),
337 ('post_code', 'rhodecode_post_code', 'unicode'),
336 ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
338 ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
337 ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
339 ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
338 ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
340 ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
339 ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
341 ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
340 ]
342 ]
341 try:
343 try:
342 for setting, form_key, type_ in settings:
344 for setting, form_key, type_ in settings:
343 sett = SettingsModel().create_or_update_setting(
345 sett = SettingsModel().create_or_update_setting(
344 setting, form_result[form_key], type_)
346 setting, form_result[form_key], type_)
345 Session().add(sett)
347 Session().add(sett)
346
348
347 Session().commit()
349 Session().commit()
348 SettingsModel().invalidate_settings_cache()
350 SettingsModel().invalidate_settings_cache()
349 h.flash(_('Updated application settings'), category='success')
351 h.flash(_('Updated application settings'), category='success')
350 except Exception:
352 except Exception:
351 log.exception("Exception while updating application settings")
353 log.exception("Exception while updating application settings")
352 h.flash(
354 h.flash(
353 _('Error occurred during updating application settings'),
355 _('Error occurred during updating application settings'),
354 category='error')
356 category='error')
355
357
356 raise HTTPFound(h.route_path('admin_settings_global'))
358 raise HTTPFound(h.route_path('admin_settings_global'))
357
359
358 @LoginRequired()
360 @LoginRequired()
359 @HasPermissionAllDecorator('hg.admin')
361 @HasPermissionAllDecorator('hg.admin')
360 @view_config(
362 @view_config(
361 route_name='admin_settings_visual', request_method='GET',
363 route_name='admin_settings_visual', request_method='GET',
362 renderer='rhodecode:templates/admin/settings/settings.mako')
364 renderer='rhodecode:templates/admin/settings/settings.mako')
363 def settings_visual(self):
365 def settings_visual(self):
364 c = self.load_default_context()
366 c = self.load_default_context()
365 c.active = 'visual'
367 c.active = 'visual'
366
368
367 data = render('rhodecode:templates/admin/settings/settings.mako',
369 data = render('rhodecode:templates/admin/settings/settings.mako',
368 self._get_template_context(c), self.request)
370 self._get_template_context(c), self.request)
369 html = formencode.htmlfill.render(
371 html = formencode.htmlfill.render(
370 data,
372 data,
371 defaults=self._form_defaults(),
373 defaults=self._form_defaults(),
372 encoding="UTF-8",
374 encoding="UTF-8",
373 force_defaults=False
375 force_defaults=False
374 )
376 )
375 return Response(html)
377 return Response(html)
376
378
377 @LoginRequired()
379 @LoginRequired()
378 @HasPermissionAllDecorator('hg.admin')
380 @HasPermissionAllDecorator('hg.admin')
379 @CSRFRequired()
381 @CSRFRequired()
380 @view_config(
382 @view_config(
381 route_name='admin_settings_visual_update', request_method='POST',
383 route_name='admin_settings_visual_update', request_method='POST',
382 renderer='rhodecode:templates/admin/settings/settings.mako')
384 renderer='rhodecode:templates/admin/settings/settings.mako')
383 def settings_visual_update(self):
385 def settings_visual_update(self):
384 _ = self.request.translate
386 _ = self.request.translate
385 c = self.load_default_context()
387 c = self.load_default_context()
386 c.active = 'visual'
388 c.active = 'visual'
387 application_form = ApplicationVisualisationForm(self.request.translate)()
389 application_form = ApplicationVisualisationForm(self.request.translate)()
388 try:
390 try:
389 form_result = application_form.to_python(dict(self.request.POST))
391 form_result = application_form.to_python(dict(self.request.POST))
390 except formencode.Invalid as errors:
392 except formencode.Invalid as errors:
391 h.flash(
393 h.flash(
392 _("Some form inputs contain invalid data."),
394 _("Some form inputs contain invalid data."),
393 category='error')
395 category='error')
394 data = render('rhodecode:templates/admin/settings/settings.mako',
396 data = render('rhodecode:templates/admin/settings/settings.mako',
395 self._get_template_context(c), self.request)
397 self._get_template_context(c), self.request)
396 html = formencode.htmlfill.render(
398 html = formencode.htmlfill.render(
397 data,
399 data,
398 defaults=errors.value,
400 defaults=errors.value,
399 errors=errors.error_dict or {},
401 errors=errors.error_dict or {},
400 prefix_error=False,
402 prefix_error=False,
401 encoding="UTF-8",
403 encoding="UTF-8",
402 force_defaults=False
404 force_defaults=False
403 )
405 )
404 return Response(html)
406 return Response(html)
405
407
406 try:
408 try:
407 settings = [
409 settings = [
408 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
410 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
409 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
411 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
410 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
412 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
411 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
413 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
412 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
414 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
413 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
415 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
414 ('show_version', 'rhodecode_show_version', 'bool'),
416 ('show_version', 'rhodecode_show_version', 'bool'),
415 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
417 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
416 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
418 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
417 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
419 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
418 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
420 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
419 ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'),
421 ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'),
420 ('support_url', 'rhodecode_support_url', 'unicode'),
422 ('support_url', 'rhodecode_support_url', 'unicode'),
421 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
423 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
422 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
424 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
423 ]
425 ]
424 for setting, form_key, type_ in settings:
426 for setting, form_key, type_ in settings:
425 sett = SettingsModel().create_or_update_setting(
427 sett = SettingsModel().create_or_update_setting(
426 setting, form_result[form_key], type_)
428 setting, form_result[form_key], type_)
427 Session().add(sett)
429 Session().add(sett)
428
430
429 Session().commit()
431 Session().commit()
430 SettingsModel().invalidate_settings_cache()
432 SettingsModel().invalidate_settings_cache()
431 h.flash(_('Updated visualisation settings'), category='success')
433 h.flash(_('Updated visualisation settings'), category='success')
432 except Exception:
434 except Exception:
433 log.exception("Exception updating visualization settings")
435 log.exception("Exception updating visualization settings")
434 h.flash(_('Error occurred during updating '
436 h.flash(_('Error occurred during updating '
435 'visualisation settings'),
437 'visualisation settings'),
436 category='error')
438 category='error')
437
439
438 raise HTTPFound(h.route_path('admin_settings_visual'))
440 raise HTTPFound(h.route_path('admin_settings_visual'))
439
441
440 @LoginRequired()
442 @LoginRequired()
441 @HasPermissionAllDecorator('hg.admin')
443 @HasPermissionAllDecorator('hg.admin')
442 @view_config(
444 @view_config(
443 route_name='admin_settings_issuetracker', request_method='GET',
445 route_name='admin_settings_issuetracker', request_method='GET',
444 renderer='rhodecode:templates/admin/settings/settings.mako')
446 renderer='rhodecode:templates/admin/settings/settings.mako')
445 def settings_issuetracker(self):
447 def settings_issuetracker(self):
446 c = self.load_default_context()
448 c = self.load_default_context()
447 c.active = 'issuetracker'
449 c.active = 'issuetracker'
448 defaults = c.rc_config
450 defaults = c.rc_config
449
451
450 entry_key = 'rhodecode_issuetracker_pat_'
452 entry_key = 'rhodecode_issuetracker_pat_'
451
453
452 c.issuetracker_entries = {}
454 c.issuetracker_entries = {}
453 for k, v in defaults.items():
455 for k, v in defaults.items():
454 if k.startswith(entry_key):
456 if k.startswith(entry_key):
455 uid = k[len(entry_key):]
457 uid = k[len(entry_key):]
456 c.issuetracker_entries[uid] = None
458 c.issuetracker_entries[uid] = None
457
459
458 for uid in c.issuetracker_entries:
460 for uid in c.issuetracker_entries:
459 c.issuetracker_entries[uid] = AttributeDict({
461 c.issuetracker_entries[uid] = AttributeDict({
460 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
462 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
461 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
463 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
462 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
464 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
463 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
465 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
464 })
466 })
465
467
466 return self._get_template_context(c)
468 return self._get_template_context(c)
467
469
468 @LoginRequired()
470 @LoginRequired()
469 @HasPermissionAllDecorator('hg.admin')
471 @HasPermissionAllDecorator('hg.admin')
470 @CSRFRequired()
472 @CSRFRequired()
471 @view_config(
473 @view_config(
472 route_name='admin_settings_issuetracker_test', request_method='POST',
474 route_name='admin_settings_issuetracker_test', request_method='POST',
473 renderer='string', xhr=True)
475 renderer='string', xhr=True)
474 def settings_issuetracker_test(self):
476 def settings_issuetracker_test(self):
475 return h.urlify_commit_message(
477 return h.urlify_commit_message(
476 self.request.POST.get('test_text', ''),
478 self.request.POST.get('test_text', ''),
477 'repo_group/test_repo1')
479 'repo_group/test_repo1')
478
480
479 @LoginRequired()
481 @LoginRequired()
480 @HasPermissionAllDecorator('hg.admin')
482 @HasPermissionAllDecorator('hg.admin')
481 @CSRFRequired()
483 @CSRFRequired()
482 @view_config(
484 @view_config(
483 route_name='admin_settings_issuetracker_update', request_method='POST',
485 route_name='admin_settings_issuetracker_update', request_method='POST',
484 renderer='rhodecode:templates/admin/settings/settings.mako')
486 renderer='rhodecode:templates/admin/settings/settings.mako')
485 def settings_issuetracker_update(self):
487 def settings_issuetracker_update(self):
486 _ = self.request.translate
488 _ = self.request.translate
487 self.load_default_context()
489 self.load_default_context()
488 settings_model = IssueTrackerSettingsModel()
490 settings_model = IssueTrackerSettingsModel()
489
491
490 try:
492 try:
491 form = IssueTrackerPatternsForm(self.request.translate)()
493 form = IssueTrackerPatternsForm(self.request.translate)()
492 data = form.to_python(self.request.POST)
494 data = form.to_python(self.request.POST)
493 except formencode.Invalid as errors:
495 except formencode.Invalid as errors:
494 log.exception('Failed to add new pattern')
496 log.exception('Failed to add new pattern')
495 error = errors
497 error = errors
496 h.flash(_('Invalid issue tracker pattern: {}'.format(error)),
498 h.flash(_('Invalid issue tracker pattern: {}'.format(error)),
497 category='error')
499 category='error')
498 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
500 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
499
501
500 if data:
502 if data:
501 for uid in data.get('delete_patterns', []):
503 for uid in data.get('delete_patterns', []):
502 settings_model.delete_entries(uid)
504 settings_model.delete_entries(uid)
503
505
504 for pattern in data.get('patterns', []):
506 for pattern in data.get('patterns', []):
505 for setting, value, type_ in pattern:
507 for setting, value, type_ in pattern:
506 sett = settings_model.create_or_update_setting(
508 sett = settings_model.create_or_update_setting(
507 setting, value, type_)
509 setting, value, type_)
508 Session().add(sett)
510 Session().add(sett)
509
511
510 Session().commit()
512 Session().commit()
511
513
512 SettingsModel().invalidate_settings_cache()
514 SettingsModel().invalidate_settings_cache()
513 h.flash(_('Updated issue tracker entries'), category='success')
515 h.flash(_('Updated issue tracker entries'), category='success')
514 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
516 raise HTTPFound(h.route_path('admin_settings_issuetracker'))
515
517
516 @LoginRequired()
518 @LoginRequired()
517 @HasPermissionAllDecorator('hg.admin')
519 @HasPermissionAllDecorator('hg.admin')
518 @CSRFRequired()
520 @CSRFRequired()
519 @view_config(
521 @view_config(
520 route_name='admin_settings_issuetracker_delete', request_method='POST',
522 route_name='admin_settings_issuetracker_delete', request_method='POST',
521 renderer='json_ext', xhr=True)
523 renderer='json_ext', xhr=True)
522 def settings_issuetracker_delete(self):
524 def settings_issuetracker_delete(self):
523 _ = self.request.translate
525 _ = self.request.translate
524 self.load_default_context()
526 self.load_default_context()
525 uid = self.request.POST.get('uid')
527 uid = self.request.POST.get('uid')
526 try:
528 try:
527 IssueTrackerSettingsModel().delete_entries(uid)
529 IssueTrackerSettingsModel().delete_entries(uid)
528 except Exception:
530 except Exception:
529 log.exception('Failed to delete issue tracker setting %s', uid)
531 log.exception('Failed to delete issue tracker setting %s', uid)
530 raise HTTPNotFound()
532 raise HTTPNotFound()
531
533
532 SettingsModel().invalidate_settings_cache()
534 SettingsModel().invalidate_settings_cache()
533 h.flash(_('Removed issue tracker entry.'), category='success')
535 h.flash(_('Removed issue tracker entry.'), category='success')
534
536
535 return {'deleted': uid}
537 return {'deleted': uid}
536
538
537 @LoginRequired()
539 @LoginRequired()
538 @HasPermissionAllDecorator('hg.admin')
540 @HasPermissionAllDecorator('hg.admin')
539 @view_config(
541 @view_config(
540 route_name='admin_settings_email', request_method='GET',
542 route_name='admin_settings_email', request_method='GET',
541 renderer='rhodecode:templates/admin/settings/settings.mako')
543 renderer='rhodecode:templates/admin/settings/settings.mako')
542 def settings_email(self):
544 def settings_email(self):
543 c = self.load_default_context()
545 c = self.load_default_context()
544 c.active = 'email'
546 c.active = 'email'
545 c.rhodecode_ini = rhodecode.CONFIG
547 c.rhodecode_ini = rhodecode.CONFIG
546
548
547 data = render('rhodecode:templates/admin/settings/settings.mako',
549 data = render('rhodecode:templates/admin/settings/settings.mako',
548 self._get_template_context(c), self.request)
550 self._get_template_context(c), self.request)
549 html = formencode.htmlfill.render(
551 html = formencode.htmlfill.render(
550 data,
552 data,
551 defaults=self._form_defaults(),
553 defaults=self._form_defaults(),
552 encoding="UTF-8",
554 encoding="UTF-8",
553 force_defaults=False
555 force_defaults=False
554 )
556 )
555 return Response(html)
557 return Response(html)
556
558
557 @LoginRequired()
559 @LoginRequired()
558 @HasPermissionAllDecorator('hg.admin')
560 @HasPermissionAllDecorator('hg.admin')
559 @CSRFRequired()
561 @CSRFRequired()
560 @view_config(
562 @view_config(
561 route_name='admin_settings_email_update', request_method='POST',
563 route_name='admin_settings_email_update', request_method='POST',
562 renderer='rhodecode:templates/admin/settings/settings.mako')
564 renderer='rhodecode:templates/admin/settings/settings.mako')
563 def settings_email_update(self):
565 def settings_email_update(self):
564 _ = self.request.translate
566 _ = self.request.translate
565 c = self.load_default_context()
567 c = self.load_default_context()
566 c.active = 'email'
568 c.active = 'email'
567
569
568 test_email = self.request.POST.get('test_email')
570 test_email = self.request.POST.get('test_email')
569
571
570 if not test_email:
572 if not test_email:
571 h.flash(_('Please enter email address'), category='error')
573 h.flash(_('Please enter email address'), category='error')
572 raise HTTPFound(h.route_path('admin_settings_email'))
574 raise HTTPFound(h.route_path('admin_settings_email'))
573
575
574 email_kwargs = {
576 email_kwargs = {
575 'date': datetime.datetime.now(),
577 'date': datetime.datetime.now(),
576 'user': self._rhodecode_db_user
578 'user': self._rhodecode_db_user
577 }
579 }
578
580
579 (subject, headers, email_body,
581 (subject, headers, email_body,
580 email_body_plaintext) = EmailNotificationModel().render_email(
582 email_body_plaintext) = EmailNotificationModel().render_email(
581 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
583 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
582
584
583 recipients = [test_email] if test_email else None
585 recipients = [test_email] if test_email else None
584
586
585 run_task(tasks.send_email, recipients, subject,
587 run_task(tasks.send_email, recipients, subject,
586 email_body_plaintext, email_body)
588 email_body_plaintext, email_body)
587
589
588 h.flash(_('Send email task created'), category='success')
590 h.flash(_('Send email task created'), category='success')
589 raise HTTPFound(h.route_path('admin_settings_email'))
591 raise HTTPFound(h.route_path('admin_settings_email'))
590
592
591 @LoginRequired()
593 @LoginRequired()
592 @HasPermissionAllDecorator('hg.admin')
594 @HasPermissionAllDecorator('hg.admin')
593 @view_config(
595 @view_config(
594 route_name='admin_settings_hooks', request_method='GET',
596 route_name='admin_settings_hooks', request_method='GET',
595 renderer='rhodecode:templates/admin/settings/settings.mako')
597 renderer='rhodecode:templates/admin/settings/settings.mako')
596 def settings_hooks(self):
598 def settings_hooks(self):
597 c = self.load_default_context()
599 c = self.load_default_context()
598 c.active = 'hooks'
600 c.active = 'hooks'
599
601
600 model = SettingsModel()
602 model = SettingsModel()
601 c.hooks = model.get_builtin_hooks()
603 c.hooks = model.get_builtin_hooks()
602 c.custom_hooks = model.get_custom_hooks()
604 c.custom_hooks = model.get_custom_hooks()
603
605
604 data = render('rhodecode:templates/admin/settings/settings.mako',
606 data = render('rhodecode:templates/admin/settings/settings.mako',
605 self._get_template_context(c), self.request)
607 self._get_template_context(c), self.request)
606 html = formencode.htmlfill.render(
608 html = formencode.htmlfill.render(
607 data,
609 data,
608 defaults=self._form_defaults(),
610 defaults=self._form_defaults(),
609 encoding="UTF-8",
611 encoding="UTF-8",
610 force_defaults=False
612 force_defaults=False
611 )
613 )
612 return Response(html)
614 return Response(html)
613
615
614 @LoginRequired()
616 @LoginRequired()
615 @HasPermissionAllDecorator('hg.admin')
617 @HasPermissionAllDecorator('hg.admin')
616 @CSRFRequired()
618 @CSRFRequired()
617 @view_config(
619 @view_config(
618 route_name='admin_settings_hooks_update', request_method='POST',
620 route_name='admin_settings_hooks_update', request_method='POST',
619 renderer='rhodecode:templates/admin/settings/settings.mako')
621 renderer='rhodecode:templates/admin/settings/settings.mako')
620 @view_config(
622 @view_config(
621 route_name='admin_settings_hooks_delete', request_method='POST',
623 route_name='admin_settings_hooks_delete', request_method='POST',
622 renderer='rhodecode:templates/admin/settings/settings.mako')
624 renderer='rhodecode:templates/admin/settings/settings.mako')
623 def settings_hooks_update(self):
625 def settings_hooks_update(self):
624 _ = self.request.translate
626 _ = self.request.translate
625 c = self.load_default_context()
627 c = self.load_default_context()
626 c.active = 'hooks'
628 c.active = 'hooks'
627 if c.visual.allow_custom_hooks_settings:
629 if c.visual.allow_custom_hooks_settings:
628 ui_key = self.request.POST.get('new_hook_ui_key')
630 ui_key = self.request.POST.get('new_hook_ui_key')
629 ui_value = self.request.POST.get('new_hook_ui_value')
631 ui_value = self.request.POST.get('new_hook_ui_value')
630
632
631 hook_id = self.request.POST.get('hook_id')
633 hook_id = self.request.POST.get('hook_id')
632 new_hook = False
634 new_hook = False
633
635
634 model = SettingsModel()
636 model = SettingsModel()
635 try:
637 try:
636 if ui_value and ui_key:
638 if ui_value and ui_key:
637 model.create_or_update_hook(ui_key, ui_value)
639 model.create_or_update_hook(ui_key, ui_value)
638 h.flash(_('Added new hook'), category='success')
640 h.flash(_('Added new hook'), category='success')
639 new_hook = True
641 new_hook = True
640 elif hook_id:
642 elif hook_id:
641 RhodeCodeUi.delete(hook_id)
643 RhodeCodeUi.delete(hook_id)
642 Session().commit()
644 Session().commit()
643
645
644 # check for edits
646 # check for edits
645 update = False
647 update = False
646 _d = self.request.POST.dict_of_lists()
648 _d = self.request.POST.dict_of_lists()
647 for k, v in zip(_d.get('hook_ui_key', []),
649 for k, v in zip(_d.get('hook_ui_key', []),
648 _d.get('hook_ui_value_new', [])):
650 _d.get('hook_ui_value_new', [])):
649 model.create_or_update_hook(k, v)
651 model.create_or_update_hook(k, v)
650 update = True
652 update = True
651
653
652 if update and not new_hook:
654 if update and not new_hook:
653 h.flash(_('Updated hooks'), category='success')
655 h.flash(_('Updated hooks'), category='success')
654 Session().commit()
656 Session().commit()
655 except Exception:
657 except Exception:
656 log.exception("Exception during hook creation")
658 log.exception("Exception during hook creation")
657 h.flash(_('Error occurred during hook creation'),
659 h.flash(_('Error occurred during hook creation'),
658 category='error')
660 category='error')
659
661
660 raise HTTPFound(h.route_path('admin_settings_hooks'))
662 raise HTTPFound(h.route_path('admin_settings_hooks'))
661
663
662 @LoginRequired()
664 @LoginRequired()
663 @HasPermissionAllDecorator('hg.admin')
665 @HasPermissionAllDecorator('hg.admin')
664 @view_config(
666 @view_config(
665 route_name='admin_settings_search', request_method='GET',
667 route_name='admin_settings_search', request_method='GET',
666 renderer='rhodecode:templates/admin/settings/settings.mako')
668 renderer='rhodecode:templates/admin/settings/settings.mako')
667 def settings_search(self):
669 def settings_search(self):
668 c = self.load_default_context()
670 c = self.load_default_context()
669 c.active = 'search'
671 c.active = 'search'
670
672
671 c.searcher = searcher_from_config(self.request.registry.settings)
673 c.searcher = searcher_from_config(self.request.registry.settings)
672 c.statistics = c.searcher.statistics(self.request.translate)
674 c.statistics = c.searcher.statistics(self.request.translate)
673
675
674 return self._get_template_context(c)
676 return self._get_template_context(c)
675
677
676 @LoginRequired()
678 @LoginRequired()
677 @HasPermissionAllDecorator('hg.admin')
679 @HasPermissionAllDecorator('hg.admin')
678 @view_config(
680 @view_config(
679 route_name='admin_settings_automation', request_method='GET',
681 route_name='admin_settings_automation', request_method='GET',
680 renderer='rhodecode:templates/admin/settings/settings.mako')
682 renderer='rhodecode:templates/admin/settings/settings.mako')
681 def settings_automation(self):
683 def settings_automation(self):
682 c = self.load_default_context()
684 c = self.load_default_context()
683 c.active = 'automation'
685 c.active = 'automation'
684
686
685 return self._get_template_context(c)
687 return self._get_template_context(c)
686
688
687 @LoginRequired()
689 @LoginRequired()
688 @HasPermissionAllDecorator('hg.admin')
690 @HasPermissionAllDecorator('hg.admin')
689 @view_config(
691 @view_config(
690 route_name='admin_settings_labs', request_method='GET',
692 route_name='admin_settings_labs', request_method='GET',
691 renderer='rhodecode:templates/admin/settings/settings.mako')
693 renderer='rhodecode:templates/admin/settings/settings.mako')
692 def settings_labs(self):
694 def settings_labs(self):
693 c = self.load_default_context()
695 c = self.load_default_context()
694 if not c.labs_active:
696 if not c.labs_active:
695 raise HTTPFound(h.route_path('admin_settings'))
697 raise HTTPFound(h.route_path('admin_settings'))
696
698
697 c.active = 'labs'
699 c.active = 'labs'
698 c.lab_settings = _LAB_SETTINGS
700 c.lab_settings = _LAB_SETTINGS
699
701
700 data = render('rhodecode:templates/admin/settings/settings.mako',
702 data = render('rhodecode:templates/admin/settings/settings.mako',
701 self._get_template_context(c), self.request)
703 self._get_template_context(c), self.request)
702 html = formencode.htmlfill.render(
704 html = formencode.htmlfill.render(
703 data,
705 data,
704 defaults=self._form_defaults(),
706 defaults=self._form_defaults(),
705 encoding="UTF-8",
707 encoding="UTF-8",
706 force_defaults=False
708 force_defaults=False
707 )
709 )
708 return Response(html)
710 return Response(html)
709
711
710 @LoginRequired()
712 @LoginRequired()
711 @HasPermissionAllDecorator('hg.admin')
713 @HasPermissionAllDecorator('hg.admin')
712 @CSRFRequired()
714 @CSRFRequired()
713 @view_config(
715 @view_config(
714 route_name='admin_settings_labs_update', request_method='POST',
716 route_name='admin_settings_labs_update', request_method='POST',
715 renderer='rhodecode:templates/admin/settings/settings.mako')
717 renderer='rhodecode:templates/admin/settings/settings.mako')
716 def settings_labs_update(self):
718 def settings_labs_update(self):
717 _ = self.request.translate
719 _ = self.request.translate
718 c = self.load_default_context()
720 c = self.load_default_context()
719 c.active = 'labs'
721 c.active = 'labs'
720
722
721 application_form = LabsSettingsForm(self.request.translate)()
723 application_form = LabsSettingsForm(self.request.translate)()
722 try:
724 try:
723 form_result = application_form.to_python(dict(self.request.POST))
725 form_result = application_form.to_python(dict(self.request.POST))
724 except formencode.Invalid as errors:
726 except formencode.Invalid as errors:
725 h.flash(
727 h.flash(
726 _("Some form inputs contain invalid data."),
728 _("Some form inputs contain invalid data."),
727 category='error')
729 category='error')
728 data = render('rhodecode:templates/admin/settings/settings.mako',
730 data = render('rhodecode:templates/admin/settings/settings.mako',
729 self._get_template_context(c), self.request)
731 self._get_template_context(c), self.request)
730 html = formencode.htmlfill.render(
732 html = formencode.htmlfill.render(
731 data,
733 data,
732 defaults=errors.value,
734 defaults=errors.value,
733 errors=errors.error_dict or {},
735 errors=errors.error_dict or {},
734 prefix_error=False,
736 prefix_error=False,
735 encoding="UTF-8",
737 encoding="UTF-8",
736 force_defaults=False
738 force_defaults=False
737 )
739 )
738 return Response(html)
740 return Response(html)
739
741
740 try:
742 try:
741 session = Session()
743 session = Session()
742 for setting in _LAB_SETTINGS:
744 for setting in _LAB_SETTINGS:
743 setting_name = setting.key[len('rhodecode_'):]
745 setting_name = setting.key[len('rhodecode_'):]
744 sett = SettingsModel().create_or_update_setting(
746 sett = SettingsModel().create_or_update_setting(
745 setting_name, form_result[setting.key], setting.type)
747 setting_name, form_result[setting.key], setting.type)
746 session.add(sett)
748 session.add(sett)
747
749
748 except Exception:
750 except Exception:
749 log.exception('Exception while updating lab settings')
751 log.exception('Exception while updating lab settings')
750 h.flash(_('Error occurred during updating labs settings'),
752 h.flash(_('Error occurred during updating labs settings'),
751 category='error')
753 category='error')
752 else:
754 else:
753 Session().commit()
755 Session().commit()
754 SettingsModel().invalidate_settings_cache()
756 SettingsModel().invalidate_settings_cache()
755 h.flash(_('Updated Labs settings'), category='success')
757 h.flash(_('Updated Labs settings'), category='success')
756 raise HTTPFound(h.route_path('admin_settings_labs'))
758 raise HTTPFound(h.route_path('admin_settings_labs'))
757
759
758 data = render('rhodecode:templates/admin/settings/settings.mako',
760 data = render('rhodecode:templates/admin/settings/settings.mako',
759 self._get_template_context(c), self.request)
761 self._get_template_context(c), self.request)
760 html = formencode.htmlfill.render(
762 html = formencode.htmlfill.render(
761 data,
763 data,
762 defaults=self._form_defaults(),
764 defaults=self._form_defaults(),
763 encoding="UTF-8",
765 encoding="UTF-8",
764 force_defaults=False
766 force_defaults=False
765 )
767 )
766 return Response(html)
768 return Response(html)
767
769
768
770
769 # :param key: name of the setting including the 'rhodecode_' prefix
771 # :param key: name of the setting including the 'rhodecode_' prefix
770 # :param type: the RhodeCodeSetting type to use.
772 # :param type: the RhodeCodeSetting type to use.
771 # :param group: the i18ned group in which we should dispaly this setting
773 # :param group: the i18ned group in which we should dispaly this setting
772 # :param label: the i18ned label we should display for this setting
774 # :param label: the i18ned label we should display for this setting
773 # :param help: the i18ned help we should dispaly for this setting
775 # :param help: the i18ned help we should dispaly for this setting
774 LabSetting = collections.namedtuple(
776 LabSetting = collections.namedtuple(
775 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
777 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
776
778
777
779
778 # This list has to be kept in sync with the form
780 # This list has to be kept in sync with the form
779 # rhodecode.model.forms.LabsSettingsForm.
781 # rhodecode.model.forms.LabsSettingsForm.
780 _LAB_SETTINGS = [
782 _LAB_SETTINGS = [
781
783
782 ]
784 ]
@@ -1,597 +1,598 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 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 permissions model for RhodeCode
22 permissions model for RhodeCode
23 """
23 """
24 import collections
24 import collections
25 import logging
25 import logging
26 import traceback
26 import traceback
27
27
28 from sqlalchemy.exc import DatabaseError
28 from sqlalchemy.exc import DatabaseError
29
29
30 from rhodecode import events
30 from rhodecode import events
31 from rhodecode.model import BaseModel
31 from rhodecode.model import BaseModel
32 from rhodecode.model.db import (
32 from rhodecode.model.db import (
33 User, Permission, UserToPerm, UserRepoToPerm, UserRepoGroupToPerm,
33 User, Permission, UserToPerm, UserRepoToPerm, UserRepoGroupToPerm,
34 UserUserGroupToPerm, UserGroup, UserGroupToPerm, UserToRepoBranchPermission)
34 UserUserGroupToPerm, UserGroup, UserGroupToPerm, UserToRepoBranchPermission)
35 from rhodecode.lib.utils2 import str2bool, safe_int
35 from rhodecode.lib.utils2 import str2bool, safe_int
36
36
37 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
38
38
39
39
40 class PermissionModel(BaseModel):
40 class PermissionModel(BaseModel):
41 """
41 """
42 Permissions model for RhodeCode
42 Permissions model for RhodeCode
43 """
43 """
44
44
45 cls = Permission
45 cls = Permission
46 global_perms = {
46 global_perms = {
47 'default_repo_create': None,
47 'default_repo_create': None,
48 # special case for create repos on write access to group
48 # special case for create repos on write access to group
49 'default_repo_create_on_write': None,
49 'default_repo_create_on_write': None,
50 'default_repo_group_create': None,
50 'default_repo_group_create': None,
51 'default_user_group_create': None,
51 'default_user_group_create': None,
52 'default_fork_create': None,
52 'default_fork_create': None,
53 'default_inherit_default_permissions': None,
53 'default_inherit_default_permissions': None,
54 'default_register': None,
54 'default_register': None,
55 'default_password_reset': None,
55 'default_password_reset': None,
56 'default_extern_activate': None,
56 'default_extern_activate': None,
57
57
58 # object permissions below
58 # object permissions below
59 'default_repo_perm': None,
59 'default_repo_perm': None,
60 'default_group_perm': None,
60 'default_group_perm': None,
61 'default_user_group_perm': None,
61 'default_user_group_perm': None,
62
62
63 # branch
63 # branch
64 'default_branch_perm': None,
64 'default_branch_perm': None,
65 }
65 }
66
66
67 def set_global_permission_choices(self, c_obj, gettext_translator):
67 def set_global_permission_choices(self, c_obj, gettext_translator):
68 _ = gettext_translator
68 _ = gettext_translator
69
69
70 c_obj.repo_perms_choices = [
70 c_obj.repo_perms_choices = [
71 ('repository.none', _('None'),),
71 ('repository.none', _('None'),),
72 ('repository.read', _('Read'),),
72 ('repository.read', _('Read'),),
73 ('repository.write', _('Write'),),
73 ('repository.write', _('Write'),),
74 ('repository.admin', _('Admin'),)]
74 ('repository.admin', _('Admin'),)]
75
75
76 c_obj.group_perms_choices = [
76 c_obj.group_perms_choices = [
77 ('group.none', _('None'),),
77 ('group.none', _('None'),),
78 ('group.read', _('Read'),),
78 ('group.read', _('Read'),),
79 ('group.write', _('Write'),),
79 ('group.write', _('Write'),),
80 ('group.admin', _('Admin'),)]
80 ('group.admin', _('Admin'),)]
81
81
82 c_obj.user_group_perms_choices = [
82 c_obj.user_group_perms_choices = [
83 ('usergroup.none', _('None'),),
83 ('usergroup.none', _('None'),),
84 ('usergroup.read', _('Read'),),
84 ('usergroup.read', _('Read'),),
85 ('usergroup.write', _('Write'),),
85 ('usergroup.write', _('Write'),),
86 ('usergroup.admin', _('Admin'),)]
86 ('usergroup.admin', _('Admin'),)]
87
87
88 c_obj.branch_perms_choices = [
88 c_obj.branch_perms_choices = [
89 ('branch.none', _('Protected/No Access'),),
89 ('branch.none', _('Protected/No Access'),),
90 ('branch.merge', _('Web merge'),),
90 ('branch.merge', _('Web merge'),),
91 ('branch.push', _('Push'),),
91 ('branch.push', _('Push'),),
92 ('branch.push_force', _('Force Push'),)]
92 ('branch.push_force', _('Force Push'),)]
93
93
94 c_obj.register_choices = [
94 c_obj.register_choices = [
95 ('hg.register.none', _('Disabled')),
95 ('hg.register.none', _('Disabled')),
96 ('hg.register.manual_activate', _('Allowed with manual account activation')),
96 ('hg.register.manual_activate', _('Allowed with manual account activation')),
97 ('hg.register.auto_activate', _('Allowed with automatic account activation')),]
97 ('hg.register.auto_activate', _('Allowed with automatic account activation')),]
98
98
99 c_obj.password_reset_choices = [
99 c_obj.password_reset_choices = [
100 ('hg.password_reset.enabled', _('Allow password recovery')),
100 ('hg.password_reset.enabled', _('Allow password recovery')),
101 ('hg.password_reset.hidden', _('Hide password recovery link')),
101 ('hg.password_reset.hidden', _('Hide password recovery link')),
102 ('hg.password_reset.disabled', _('Disable password recovery')),]
102 ('hg.password_reset.disabled', _('Disable password recovery')),]
103
103
104 c_obj.extern_activate_choices = [
104 c_obj.extern_activate_choices = [
105 ('hg.extern_activate.manual', _('Manual activation of external account')),
105 ('hg.extern_activate.manual', _('Manual activation of external account')),
106 ('hg.extern_activate.auto', _('Automatic activation of external account')),]
106 ('hg.extern_activate.auto', _('Automatic activation of external account')),]
107
107
108 c_obj.repo_create_choices = [
108 c_obj.repo_create_choices = [
109 ('hg.create.none', _('Disabled')),
109 ('hg.create.none', _('Disabled')),
110 ('hg.create.repository', _('Enabled'))]
110 ('hg.create.repository', _('Enabled'))]
111
111
112 c_obj.repo_create_on_write_choices = [
112 c_obj.repo_create_on_write_choices = [
113 ('hg.create.write_on_repogroup.false', _('Disabled')),
113 ('hg.create.write_on_repogroup.false', _('Disabled')),
114 ('hg.create.write_on_repogroup.true', _('Enabled'))]
114 ('hg.create.write_on_repogroup.true', _('Enabled'))]
115
115
116 c_obj.user_group_create_choices = [
116 c_obj.user_group_create_choices = [
117 ('hg.usergroup.create.false', _('Disabled')),
117 ('hg.usergroup.create.false', _('Disabled')),
118 ('hg.usergroup.create.true', _('Enabled'))]
118 ('hg.usergroup.create.true', _('Enabled'))]
119
119
120 c_obj.repo_group_create_choices = [
120 c_obj.repo_group_create_choices = [
121 ('hg.repogroup.create.false', _('Disabled')),
121 ('hg.repogroup.create.false', _('Disabled')),
122 ('hg.repogroup.create.true', _('Enabled'))]
122 ('hg.repogroup.create.true', _('Enabled'))]
123
123
124 c_obj.fork_choices = [
124 c_obj.fork_choices = [
125 ('hg.fork.none', _('Disabled')),
125 ('hg.fork.none', _('Disabled')),
126 ('hg.fork.repository', _('Enabled'))]
126 ('hg.fork.repository', _('Enabled'))]
127
127
128 c_obj.inherit_default_permission_choices = [
128 c_obj.inherit_default_permission_choices = [
129 ('hg.inherit_default_perms.false', _('Disabled')),
129 ('hg.inherit_default_perms.false', _('Disabled')),
130 ('hg.inherit_default_perms.true', _('Enabled'))]
130 ('hg.inherit_default_perms.true', _('Enabled'))]
131
131
132 def get_default_perms(self, object_perms, suffix):
132 def get_default_perms(self, object_perms, suffix):
133 defaults = {}
133 defaults = {}
134 for perm in object_perms:
134 for perm in object_perms:
135 # perms
135 # perms
136 if perm.permission.permission_name.startswith('repository.'):
136 if perm.permission.permission_name.startswith('repository.'):
137 defaults['default_repo_perm' + suffix] = perm.permission.permission_name
137 defaults['default_repo_perm' + suffix] = perm.permission.permission_name
138
138
139 if perm.permission.permission_name.startswith('group.'):
139 if perm.permission.permission_name.startswith('group.'):
140 defaults['default_group_perm' + suffix] = perm.permission.permission_name
140 defaults['default_group_perm' + suffix] = perm.permission.permission_name
141
141
142 if perm.permission.permission_name.startswith('usergroup.'):
142 if perm.permission.permission_name.startswith('usergroup.'):
143 defaults['default_user_group_perm' + suffix] = perm.permission.permission_name
143 defaults['default_user_group_perm' + suffix] = perm.permission.permission_name
144
144
145 # branch
145 # branch
146 if perm.permission.permission_name.startswith('branch.'):
146 if perm.permission.permission_name.startswith('branch.'):
147 defaults['default_branch_perm' + suffix] = perm.permission.permission_name
147 defaults['default_branch_perm' + suffix] = perm.permission.permission_name
148
148
149 # creation of objects
149 # creation of objects
150 if perm.permission.permission_name.startswith('hg.create.write_on_repogroup'):
150 if perm.permission.permission_name.startswith('hg.create.write_on_repogroup'):
151 defaults['default_repo_create_on_write' + suffix] = perm.permission.permission_name
151 defaults['default_repo_create_on_write' + suffix] = perm.permission.permission_name
152
152
153 elif perm.permission.permission_name.startswith('hg.create.'):
153 elif perm.permission.permission_name.startswith('hg.create.'):
154 defaults['default_repo_create' + suffix] = perm.permission.permission_name
154 defaults['default_repo_create' + suffix] = perm.permission.permission_name
155
155
156 if perm.permission.permission_name.startswith('hg.fork.'):
156 if perm.permission.permission_name.startswith('hg.fork.'):
157 defaults['default_fork_create' + suffix] = perm.permission.permission_name
157 defaults['default_fork_create' + suffix] = perm.permission.permission_name
158
158
159 if perm.permission.permission_name.startswith('hg.inherit_default_perms.'):
159 if perm.permission.permission_name.startswith('hg.inherit_default_perms.'):
160 defaults['default_inherit_default_permissions' + suffix] = perm.permission.permission_name
160 defaults['default_inherit_default_permissions' + suffix] = perm.permission.permission_name
161
161
162 if perm.permission.permission_name.startswith('hg.repogroup.'):
162 if perm.permission.permission_name.startswith('hg.repogroup.'):
163 defaults['default_repo_group_create' + suffix] = perm.permission.permission_name
163 defaults['default_repo_group_create' + suffix] = perm.permission.permission_name
164
164
165 if perm.permission.permission_name.startswith('hg.usergroup.'):
165 if perm.permission.permission_name.startswith('hg.usergroup.'):
166 defaults['default_user_group_create' + suffix] = perm.permission.permission_name
166 defaults['default_user_group_create' + suffix] = perm.permission.permission_name
167
167
168 # registration and external account activation
168 # registration and external account activation
169 if perm.permission.permission_name.startswith('hg.register.'):
169 if perm.permission.permission_name.startswith('hg.register.'):
170 defaults['default_register' + suffix] = perm.permission.permission_name
170 defaults['default_register' + suffix] = perm.permission.permission_name
171
171
172 if perm.permission.permission_name.startswith('hg.password_reset.'):
172 if perm.permission.permission_name.startswith('hg.password_reset.'):
173 defaults['default_password_reset' + suffix] = perm.permission.permission_name
173 defaults['default_password_reset' + suffix] = perm.permission.permission_name
174
174
175 if perm.permission.permission_name.startswith('hg.extern_activate.'):
175 if perm.permission.permission_name.startswith('hg.extern_activate.'):
176 defaults['default_extern_activate' + suffix] = perm.permission.permission_name
176 defaults['default_extern_activate' + suffix] = perm.permission.permission_name
177
177
178 return defaults
178 return defaults
179
179
180 def _make_new_user_perm(self, user, perm_name):
180 def _make_new_user_perm(self, user, perm_name):
181 log.debug('Creating new user permission:%s', perm_name)
181 log.debug('Creating new user permission:%s', perm_name)
182 new = UserToPerm()
182 new = UserToPerm()
183 new.user = user
183 new.user = user
184 new.permission = Permission.get_by_key(perm_name)
184 new.permission = Permission.get_by_key(perm_name)
185 return new
185 return new
186
186
187 def _make_new_user_group_perm(self, user_group, perm_name):
187 def _make_new_user_group_perm(self, user_group, perm_name):
188 log.debug('Creating new user group permission:%s', perm_name)
188 log.debug('Creating new user group permission:%s', perm_name)
189 new = UserGroupToPerm()
189 new = UserGroupToPerm()
190 new.users_group = user_group
190 new.users_group = user_group
191 new.permission = Permission.get_by_key(perm_name)
191 new.permission = Permission.get_by_key(perm_name)
192 return new
192 return new
193
193
194 def _keep_perm(self, perm_name, keep_fields):
194 def _keep_perm(self, perm_name, keep_fields):
195 def get_pat(field_name):
195 def get_pat(field_name):
196 return {
196 return {
197 # global perms
197 # global perms
198 'default_repo_create': 'hg.create.',
198 'default_repo_create': 'hg.create.',
199 # special case for create repos on write access to group
199 # special case for create repos on write access to group
200 'default_repo_create_on_write': 'hg.create.write_on_repogroup.',
200 'default_repo_create_on_write': 'hg.create.write_on_repogroup.',
201 'default_repo_group_create': 'hg.repogroup.create.',
201 'default_repo_group_create': 'hg.repogroup.create.',
202 'default_user_group_create': 'hg.usergroup.create.',
202 'default_user_group_create': 'hg.usergroup.create.',
203 'default_fork_create': 'hg.fork.',
203 'default_fork_create': 'hg.fork.',
204 'default_inherit_default_permissions': 'hg.inherit_default_perms.',
204 'default_inherit_default_permissions': 'hg.inherit_default_perms.',
205
205
206 # application perms
206 # application perms
207 'default_register': 'hg.register.',
207 'default_register': 'hg.register.',
208 'default_password_reset': 'hg.password_reset.',
208 'default_password_reset': 'hg.password_reset.',
209 'default_extern_activate': 'hg.extern_activate.',
209 'default_extern_activate': 'hg.extern_activate.',
210
210
211 # object permissions below
211 # object permissions below
212 'default_repo_perm': 'repository.',
212 'default_repo_perm': 'repository.',
213 'default_group_perm': 'group.',
213 'default_group_perm': 'group.',
214 'default_user_group_perm': 'usergroup.',
214 'default_user_group_perm': 'usergroup.',
215 # branch
215 # branch
216 'default_branch_perm': 'branch.',
216 'default_branch_perm': 'branch.',
217
217
218 }[field_name]
218 }[field_name]
219 for field in keep_fields:
219 for field in keep_fields:
220 pat = get_pat(field)
220 pat = get_pat(field)
221 if perm_name.startswith(pat):
221 if perm_name.startswith(pat):
222 return True
222 return True
223 return False
223 return False
224
224
225 def _clear_object_perm(self, object_perms, preserve=None):
225 def _clear_object_perm(self, object_perms, preserve=None):
226 preserve = preserve or []
226 preserve = preserve or []
227 _deleted = []
227 _deleted = []
228 for perm in object_perms:
228 for perm in object_perms:
229 perm_name = perm.permission.permission_name
229 perm_name = perm.permission.permission_name
230 if not self._keep_perm(perm_name, keep_fields=preserve):
230 if not self._keep_perm(perm_name, keep_fields=preserve):
231 _deleted.append(perm_name)
231 _deleted.append(perm_name)
232 self.sa.delete(perm)
232 self.sa.delete(perm)
233 return _deleted
233 return _deleted
234
234
235 def _clear_user_perms(self, user_id, preserve=None):
235 def _clear_user_perms(self, user_id, preserve=None):
236 perms = self.sa.query(UserToPerm)\
236 perms = self.sa.query(UserToPerm)\
237 .filter(UserToPerm.user_id == user_id)\
237 .filter(UserToPerm.user_id == user_id)\
238 .all()
238 .all()
239 return self._clear_object_perm(perms, preserve=preserve)
239 return self._clear_object_perm(perms, preserve=preserve)
240
240
241 def _clear_user_group_perms(self, user_group_id, preserve=None):
241 def _clear_user_group_perms(self, user_group_id, preserve=None):
242 perms = self.sa.query(UserGroupToPerm)\
242 perms = self.sa.query(UserGroupToPerm)\
243 .filter(UserGroupToPerm.users_group_id == user_group_id)\
243 .filter(UserGroupToPerm.users_group_id == user_group_id)\
244 .all()
244 .all()
245 return self._clear_object_perm(perms, preserve=preserve)
245 return self._clear_object_perm(perms, preserve=preserve)
246
246
247 def _set_new_object_perms(self, obj_type, object, form_result, preserve=None):
247 def _set_new_object_perms(self, obj_type, object, form_result, preserve=None):
248 # clear current entries, to make this function idempotent
248 # clear current entries, to make this function idempotent
249 # it will fix even if we define more permissions or permissions
249 # it will fix even if we define more permissions or permissions
250 # are somehow missing
250 # are somehow missing
251 preserve = preserve or []
251 preserve = preserve or []
252 _global_perms = self.global_perms.copy()
252 _global_perms = self.global_perms.copy()
253 if obj_type not in ['user', 'user_group']:
253 if obj_type not in ['user', 'user_group']:
254 raise ValueError("obj_type must be on of 'user' or 'user_group'")
254 raise ValueError("obj_type must be on of 'user' or 'user_group'")
255 global_perms = len(_global_perms)
255 global_perms = len(_global_perms)
256 default_user_perms = len(Permission.DEFAULT_USER_PERMISSIONS)
256 default_user_perms = len(Permission.DEFAULT_USER_PERMISSIONS)
257 if global_perms != default_user_perms:
257 if global_perms != default_user_perms:
258 raise Exception(
258 raise Exception(
259 'Inconsistent permissions definition. Got {} vs {}'.format(
259 'Inconsistent permissions definition. Got {} vs {}'.format(
260 global_perms, default_user_perms))
260 global_perms, default_user_perms))
261
261
262 if obj_type == 'user':
262 if obj_type == 'user':
263 self._clear_user_perms(object.user_id, preserve)
263 self._clear_user_perms(object.user_id, preserve)
264 if obj_type == 'user_group':
264 if obj_type == 'user_group':
265 self._clear_user_group_perms(object.users_group_id, preserve)
265 self._clear_user_group_perms(object.users_group_id, preserve)
266
266
267 # now kill the keys that we want to preserve from the form.
267 # now kill the keys that we want to preserve from the form.
268 for key in preserve:
268 for key in preserve:
269 del _global_perms[key]
269 del _global_perms[key]
270
270
271 for k in _global_perms.copy():
271 for k in _global_perms.copy():
272 _global_perms[k] = form_result[k]
272 _global_perms[k] = form_result[k]
273
273
274 # at that stage we validate all are passed inside form_result
274 # at that stage we validate all are passed inside form_result
275 for _perm_key, perm_value in _global_perms.items():
275 for _perm_key, perm_value in _global_perms.items():
276 if perm_value is None:
276 if perm_value is None:
277 raise ValueError('Missing permission for %s' % (_perm_key,))
277 raise ValueError('Missing permission for %s' % (_perm_key,))
278
278
279 if obj_type == 'user':
279 if obj_type == 'user':
280 p = self._make_new_user_perm(object, perm_value)
280 p = self._make_new_user_perm(object, perm_value)
281 self.sa.add(p)
281 self.sa.add(p)
282 if obj_type == 'user_group':
282 if obj_type == 'user_group':
283 p = self._make_new_user_group_perm(object, perm_value)
283 p = self._make_new_user_group_perm(object, perm_value)
284 self.sa.add(p)
284 self.sa.add(p)
285
285
286 def _set_new_user_perms(self, user, form_result, preserve=None):
286 def _set_new_user_perms(self, user, form_result, preserve=None):
287 return self._set_new_object_perms(
287 return self._set_new_object_perms(
288 'user', user, form_result, preserve)
288 'user', user, form_result, preserve)
289
289
290 def _set_new_user_group_perms(self, user_group, form_result, preserve=None):
290 def _set_new_user_group_perms(self, user_group, form_result, preserve=None):
291 return self._set_new_object_perms(
291 return self._set_new_object_perms(
292 'user_group', user_group, form_result, preserve)
292 'user_group', user_group, form_result, preserve)
293
293
294 def set_new_user_perms(self, user, form_result):
294 def set_new_user_perms(self, user, form_result):
295 # calculate what to preserve from what is given in form_result
295 # calculate what to preserve from what is given in form_result
296 preserve = set(self.global_perms.keys()).difference(set(form_result.keys()))
296 preserve = set(self.global_perms.keys()).difference(set(form_result.keys()))
297 return self._set_new_user_perms(user, form_result, preserve)
297 return self._set_new_user_perms(user, form_result, preserve)
298
298
299 def set_new_user_group_perms(self, user_group, form_result):
299 def set_new_user_group_perms(self, user_group, form_result):
300 # calculate what to preserve from what is given in form_result
300 # calculate what to preserve from what is given in form_result
301 preserve = set(self.global_perms.keys()).difference(set(form_result.keys()))
301 preserve = set(self.global_perms.keys()).difference(set(form_result.keys()))
302 return self._set_new_user_group_perms(user_group, form_result, preserve)
302 return self._set_new_user_group_perms(user_group, form_result, preserve)
303
303
304 def create_permissions(self):
304 def create_permissions(self):
305 """
305 """
306 Create permissions for whole system
306 Create permissions for whole system
307 """
307 """
308 for p in Permission.PERMS:
308 for p in Permission.PERMS:
309 if not Permission.get_by_key(p[0]):
309 if not Permission.get_by_key(p[0]):
310 new_perm = Permission()
310 new_perm = Permission()
311 new_perm.permission_name = p[0]
311 new_perm.permission_name = p[0]
312 new_perm.permission_longname = p[0] # translation err with p[1]
312 new_perm.permission_longname = p[0] # translation err with p[1]
313 self.sa.add(new_perm)
313 self.sa.add(new_perm)
314
314
315 def _create_default_object_permission(self, obj_type, obj, obj_perms,
315 def _create_default_object_permission(self, obj_type, obj, obj_perms,
316 force=False):
316 force=False):
317 if obj_type not in ['user', 'user_group']:
317 if obj_type not in ['user', 'user_group']:
318 raise ValueError("obj_type must be on of 'user' or 'user_group'")
318 raise ValueError("obj_type must be on of 'user' or 'user_group'")
319
319
320 def _get_group(perm_name):
320 def _get_group(perm_name):
321 return '.'.join(perm_name.split('.')[:1])
321 return '.'.join(perm_name.split('.')[:1])
322
322
323 defined_perms_groups = map(
323 defined_perms_groups = map(
324 _get_group, (x.permission.permission_name for x in obj_perms))
324 _get_group, (x.permission.permission_name for x in obj_perms))
325 log.debug('GOT ALREADY DEFINED:%s', obj_perms)
325 log.debug('GOT ALREADY DEFINED:%s', obj_perms)
326
326
327 if force:
327 if force:
328 self._clear_object_perm(obj_perms)
328 self._clear_object_perm(obj_perms)
329 self.sa.commit()
329 self.sa.commit()
330 defined_perms_groups = []
330 defined_perms_groups = []
331 # for every default permission that needs to be created, we check if
331 # for every default permission that needs to be created, we check if
332 # it's group is already defined, if it's not we create default perm
332 # it's group is already defined, if it's not we create default perm
333 for perm_name in Permission.DEFAULT_USER_PERMISSIONS:
333 for perm_name in Permission.DEFAULT_USER_PERMISSIONS:
334 gr = _get_group(perm_name)
334 gr = _get_group(perm_name)
335 if gr not in defined_perms_groups:
335 if gr not in defined_perms_groups:
336 log.debug('GR:%s not found, creating permission %s',
336 log.debug('GR:%s not found, creating permission %s',
337 gr, perm_name)
337 gr, perm_name)
338 if obj_type == 'user':
338 if obj_type == 'user':
339 new_perm = self._make_new_user_perm(obj, perm_name)
339 new_perm = self._make_new_user_perm(obj, perm_name)
340 self.sa.add(new_perm)
340 self.sa.add(new_perm)
341 if obj_type == 'user_group':
341 if obj_type == 'user_group':
342 new_perm = self._make_new_user_group_perm(obj, perm_name)
342 new_perm = self._make_new_user_group_perm(obj, perm_name)
343 self.sa.add(new_perm)
343 self.sa.add(new_perm)
344
344
345 def create_default_user_permissions(self, user, force=False):
345 def create_default_user_permissions(self, user, force=False):
346 """
346 """
347 Creates only missing default permissions for user, if force is set it
347 Creates only missing default permissions for user, if force is set it
348 resets the default permissions for that user
348 resets the default permissions for that user
349
349
350 :param user:
350 :param user:
351 :param force:
351 :param force:
352 """
352 """
353 user = self._get_user(user)
353 user = self._get_user(user)
354 obj_perms = UserToPerm.query().filter(UserToPerm.user == user).all()
354 obj_perms = UserToPerm.query().filter(UserToPerm.user == user).all()
355 return self._create_default_object_permission(
355 return self._create_default_object_permission(
356 'user', user, obj_perms, force)
356 'user', user, obj_perms, force)
357
357
358 def create_default_user_group_permissions(self, user_group, force=False):
358 def create_default_user_group_permissions(self, user_group, force=False):
359 """
359 """
360 Creates only missing default permissions for user group, if force is
360 Creates only missing default permissions for user group, if force is
361 set it resets the default permissions for that user group
361 set it resets the default permissions for that user group
362
362
363 :param user_group:
363 :param user_group:
364 :param force:
364 :param force:
365 """
365 """
366 user_group = self._get_user_group(user_group)
366 user_group = self._get_user_group(user_group)
367 obj_perms = UserToPerm.query().filter(UserGroupToPerm.users_group == user_group).all()
367 obj_perms = UserToPerm.query().filter(UserGroupToPerm.users_group == user_group).all()
368 return self._create_default_object_permission(
368 return self._create_default_object_permission(
369 'user_group', user_group, obj_perms, force)
369 'user_group', user_group, obj_perms, force)
370
370
371 def update_application_permissions(self, form_result):
371 def update_application_permissions(self, form_result):
372 if 'perm_user_id' in form_result:
372 if 'perm_user_id' in form_result:
373 perm_user = User.get(safe_int(form_result['perm_user_id']))
373 perm_user = User.get(safe_int(form_result['perm_user_id']))
374 else:
374 else:
375 # used mostly to do lookup for default user
375 # used mostly to do lookup for default user
376 perm_user = User.get_by_username(form_result['perm_user_name'])
376 perm_user = User.get_by_username(form_result['perm_user_name'])
377
377
378 try:
378 try:
379 # stage 1 set anonymous access
379 # stage 1 set anonymous access
380 if perm_user.username == User.DEFAULT_USER:
380 if perm_user.username == User.DEFAULT_USER:
381 perm_user.active = str2bool(form_result['anonymous'])
381 perm_user.active = str2bool(form_result['anonymous'])
382 self.sa.add(perm_user)
382 self.sa.add(perm_user)
383
383
384 # stage 2 reset defaults and set them from form data
384 # stage 2 reset defaults and set them from form data
385 self._set_new_user_perms(perm_user, form_result, preserve=[
385 self._set_new_user_perms(perm_user, form_result, preserve=[
386 'default_repo_perm',
386 'default_repo_perm',
387 'default_group_perm',
387 'default_group_perm',
388 'default_user_group_perm',
388 'default_user_group_perm',
389 'default_branch_perm',
389 'default_branch_perm',
390
390
391 'default_repo_group_create',
391 'default_repo_group_create',
392 'default_user_group_create',
392 'default_user_group_create',
393 'default_repo_create_on_write',
393 'default_repo_create_on_write',
394 'default_repo_create',
394 'default_repo_create',
395 'default_fork_create',
395 'default_fork_create',
396 'default_inherit_default_permissions',])
396 'default_inherit_default_permissions',])
397
397
398 self.sa.commit()
398 self.sa.commit()
399 except (DatabaseError,):
399 except (DatabaseError,):
400 log.error(traceback.format_exc())
400 log.error(traceback.format_exc())
401 self.sa.rollback()
401 self.sa.rollback()
402 raise
402 raise
403
403
404 def update_user_permissions(self, form_result):
404 def update_user_permissions(self, form_result):
405 if 'perm_user_id' in form_result:
405 if 'perm_user_id' in form_result:
406 perm_user = User.get(safe_int(form_result['perm_user_id']))
406 perm_user = User.get(safe_int(form_result['perm_user_id']))
407 else:
407 else:
408 # used mostly to do lookup for default user
408 # used mostly to do lookup for default user
409 perm_user = User.get_by_username(form_result['perm_user_name'])
409 perm_user = User.get_by_username(form_result['perm_user_name'])
410 try:
410 try:
411 # stage 2 reset defaults and set them from form data
411 # stage 2 reset defaults and set them from form data
412 self._set_new_user_perms(perm_user, form_result, preserve=[
412 self._set_new_user_perms(perm_user, form_result, preserve=[
413 'default_repo_perm',
413 'default_repo_perm',
414 'default_group_perm',
414 'default_group_perm',
415 'default_user_group_perm',
415 'default_user_group_perm',
416 'default_branch_perm',
416 'default_branch_perm',
417
417
418 'default_register',
418 'default_register',
419 'default_password_reset',
419 'default_password_reset',
420 'default_extern_activate'])
420 'default_extern_activate'])
421 self.sa.commit()
421 self.sa.commit()
422 except (DatabaseError,):
422 except (DatabaseError,):
423 log.error(traceback.format_exc())
423 log.error(traceback.format_exc())
424 self.sa.rollback()
424 self.sa.rollback()
425 raise
425 raise
426
426
427 def update_user_group_permissions(self, form_result):
427 def update_user_group_permissions(self, form_result):
428 if 'perm_user_group_id' in form_result:
428 if 'perm_user_group_id' in form_result:
429 perm_user_group = UserGroup.get(safe_int(form_result['perm_user_group_id']))
429 perm_user_group = UserGroup.get(safe_int(form_result['perm_user_group_id']))
430 else:
430 else:
431 # used mostly to do lookup for default user
431 # used mostly to do lookup for default user
432 perm_user_group = UserGroup.get_by_group_name(form_result['perm_user_group_name'])
432 perm_user_group = UserGroup.get_by_group_name(form_result['perm_user_group_name'])
433 try:
433 try:
434 # stage 2 reset defaults and set them from form data
434 # stage 2 reset defaults and set them from form data
435 self._set_new_user_group_perms(perm_user_group, form_result, preserve=[
435 self._set_new_user_group_perms(perm_user_group, form_result, preserve=[
436 'default_repo_perm',
436 'default_repo_perm',
437 'default_group_perm',
437 'default_group_perm',
438 'default_user_group_perm',
438 'default_user_group_perm',
439 'default_branch_perm',
439 'default_branch_perm',
440
440
441 'default_register',
441 'default_register',
442 'default_password_reset',
442 'default_password_reset',
443 'default_extern_activate'])
443 'default_extern_activate'])
444 self.sa.commit()
444 self.sa.commit()
445 except (DatabaseError,):
445 except (DatabaseError,):
446 log.error(traceback.format_exc())
446 log.error(traceback.format_exc())
447 self.sa.rollback()
447 self.sa.rollback()
448 raise
448 raise
449
449
450 def update_object_permissions(self, form_result):
450 def update_object_permissions(self, form_result):
451 if 'perm_user_id' in form_result:
451 if 'perm_user_id' in form_result:
452 perm_user = User.get(safe_int(form_result['perm_user_id']))
452 perm_user = User.get(safe_int(form_result['perm_user_id']))
453 else:
453 else:
454 # used mostly to do lookup for default user
454 # used mostly to do lookup for default user
455 perm_user = User.get_by_username(form_result['perm_user_name'])
455 perm_user = User.get_by_username(form_result['perm_user_name'])
456 try:
456 try:
457
457
458 # stage 2 reset defaults and set them from form data
458 # stage 2 reset defaults and set them from form data
459 self._set_new_user_perms(perm_user, form_result, preserve=[
459 self._set_new_user_perms(perm_user, form_result, preserve=[
460 'default_repo_group_create',
460 'default_repo_group_create',
461 'default_user_group_create',
461 'default_user_group_create',
462 'default_repo_create_on_write',
462 'default_repo_create_on_write',
463 'default_repo_create',
463 'default_repo_create',
464 'default_fork_create',
464 'default_fork_create',
465 'default_inherit_default_permissions',
465 'default_inherit_default_permissions',
466 'default_branch_perm',
466 'default_branch_perm',
467
467
468 'default_register',
468 'default_register',
469 'default_password_reset',
469 'default_password_reset',
470 'default_extern_activate'])
470 'default_extern_activate'])
471
471
472 # overwrite default repo permissions
472 # overwrite default repo permissions
473 if form_result['overwrite_default_repo']:
473 if form_result['overwrite_default_repo']:
474 _def_name = form_result['default_repo_perm'].split('repository.')[-1]
474 _def_name = form_result['default_repo_perm'].split('repository.')[-1]
475 _def = Permission.get_by_key('repository.' + _def_name)
475 _def = Permission.get_by_key('repository.' + _def_name)
476 for r2p in self.sa.query(UserRepoToPerm)\
476 for r2p in self.sa.query(UserRepoToPerm)\
477 .filter(UserRepoToPerm.user == perm_user)\
477 .filter(UserRepoToPerm.user == perm_user)\
478 .all():
478 .all():
479 # don't reset PRIVATE repositories
479 # don't reset PRIVATE repositories
480 if not r2p.repository.private:
480 if not r2p.repository.private:
481 r2p.permission = _def
481 r2p.permission = _def
482 self.sa.add(r2p)
482 self.sa.add(r2p)
483
483
484 # overwrite default repo group permissions
484 # overwrite default repo group permissions
485 if form_result['overwrite_default_group']:
485 if form_result['overwrite_default_group']:
486 _def_name = form_result['default_group_perm'].split('group.')[-1]
486 _def_name = form_result['default_group_perm'].split('group.')[-1]
487 _def = Permission.get_by_key('group.' + _def_name)
487 _def = Permission.get_by_key('group.' + _def_name)
488 for g2p in self.sa.query(UserRepoGroupToPerm)\
488 for g2p in self.sa.query(UserRepoGroupToPerm)\
489 .filter(UserRepoGroupToPerm.user == perm_user)\
489 .filter(UserRepoGroupToPerm.user == perm_user)\
490 .all():
490 .all():
491 g2p.permission = _def
491 g2p.permission = _def
492 self.sa.add(g2p)
492 self.sa.add(g2p)
493
493
494 # overwrite default user group permissions
494 # overwrite default user group permissions
495 if form_result['overwrite_default_user_group']:
495 if form_result['overwrite_default_user_group']:
496 _def_name = form_result['default_user_group_perm'].split('usergroup.')[-1]
496 _def_name = form_result['default_user_group_perm'].split('usergroup.')[-1]
497 # user groups
497 # user groups
498 _def = Permission.get_by_key('usergroup.' + _def_name)
498 _def = Permission.get_by_key('usergroup.' + _def_name)
499 for g2p in self.sa.query(UserUserGroupToPerm)\
499 for g2p in self.sa.query(UserUserGroupToPerm)\
500 .filter(UserUserGroupToPerm.user == perm_user)\
500 .filter(UserUserGroupToPerm.user == perm_user)\
501 .all():
501 .all():
502 g2p.permission = _def
502 g2p.permission = _def
503 self.sa.add(g2p)
503 self.sa.add(g2p)
504
504
505 # COMMIT
505 # COMMIT
506 self.sa.commit()
506 self.sa.commit()
507 except (DatabaseError,):
507 except (DatabaseError,):
508 log.exception('Failed to set default object permissions')
508 log.exception('Failed to set default object permissions')
509 self.sa.rollback()
509 self.sa.rollback()
510 raise
510 raise
511
511
512 def update_branch_permissions(self, form_result):
512 def update_branch_permissions(self, form_result):
513 if 'perm_user_id' in form_result:
513 if 'perm_user_id' in form_result:
514 perm_user = User.get(safe_int(form_result['perm_user_id']))
514 perm_user = User.get(safe_int(form_result['perm_user_id']))
515 else:
515 else:
516 # used mostly to do lookup for default user
516 # used mostly to do lookup for default user
517 perm_user = User.get_by_username(form_result['perm_user_name'])
517 perm_user = User.get_by_username(form_result['perm_user_name'])
518 try:
518 try:
519
519
520 # stage 2 reset defaults and set them from form data
520 # stage 2 reset defaults and set them from form data
521 self._set_new_user_perms(perm_user, form_result, preserve=[
521 self._set_new_user_perms(perm_user, form_result, preserve=[
522 'default_repo_perm',
522 'default_repo_perm',
523 'default_group_perm',
523 'default_group_perm',
524 'default_user_group_perm',
524 'default_user_group_perm',
525
525
526 'default_repo_group_create',
526 'default_repo_group_create',
527 'default_user_group_create',
527 'default_user_group_create',
528 'default_repo_create_on_write',
528 'default_repo_create_on_write',
529 'default_repo_create',
529 'default_repo_create',
530 'default_fork_create',
530 'default_fork_create',
531 'default_inherit_default_permissions',
531 'default_inherit_default_permissions',
532
532
533 'default_register',
533 'default_register',
534 'default_password_reset',
534 'default_password_reset',
535 'default_extern_activate'])
535 'default_extern_activate'])
536
536
537 # overwrite default branch permissions
537 # overwrite default branch permissions
538 if form_result['overwrite_default_branch']:
538 if form_result['overwrite_default_branch']:
539 _def_name = \
539 _def_name = \
540 form_result['default_branch_perm'].split('branch.')[-1]
540 form_result['default_branch_perm'].split('branch.')[-1]
541
541
542 _def = Permission.get_by_key('branch.' + _def_name)
542 _def = Permission.get_by_key('branch.' + _def_name)
543
543
544 user_perms = UserToRepoBranchPermission.query()\
544 user_perms = UserToRepoBranchPermission.query()\
545 .join(UserToRepoBranchPermission.user_repo_to_perm)\
545 .join(UserToRepoBranchPermission.user_repo_to_perm)\
546 .filter(UserRepoToPerm.user == perm_user).all()
546 .filter(UserRepoToPerm.user == perm_user).all()
547
547
548 for g2p in user_perms:
548 for g2p in user_perms:
549 g2p.permission = _def
549 g2p.permission = _def
550 self.sa.add(g2p)
550 self.sa.add(g2p)
551
551
552 # COMMIT
552 # COMMIT
553 self.sa.commit()
553 self.sa.commit()
554 except (DatabaseError,):
554 except (DatabaseError,):
555 log.exception('Failed to set default branch permissions')
555 log.exception('Failed to set default branch permissions')
556 self.sa.rollback()
556 self.sa.rollback()
557 raise
557 raise
558
558
559 def get_users_with_repo_write(self, db_repo):
559 def get_users_with_repo_write(self, db_repo):
560 write_plus = ['repository.write', 'repository.admin']
560 write_plus = ['repository.write', 'repository.admin']
561 default_user_id = User.get_default_user_id()
561 default_user_id = User.get_default_user_id()
562 user_write_permissions = collections.OrderedDict()
562 user_write_permissions = collections.OrderedDict()
563
563
564 # write+ and DEFAULT user for inheritance
564 # write+ and DEFAULT user for inheritance
565 for perm in db_repo.permissions():
565 for perm in db_repo.permissions():
566 if perm.permission in write_plus or perm.user_id == default_user_id:
566 if perm.permission in write_plus or perm.user_id == default_user_id:
567 user_write_permissions[perm.user_id] = perm
567 user_write_permissions[perm.user_id] = perm
568 return user_write_permissions
568 return user_write_permissions
569
569
570 def get_user_groups_with_repo_write(self, db_repo):
570 def get_user_groups_with_repo_write(self, db_repo):
571 write_plus = ['repository.write', 'repository.admin']
571 write_plus = ['repository.write', 'repository.admin']
572 user_group_write_permissions = collections.OrderedDict()
572 user_group_write_permissions = collections.OrderedDict()
573
573
574 # write+ and DEFAULT user for inheritance
574 # write+ and DEFAULT user for inheritance
575 for p in db_repo.permission_user_groups():
575 for p in db_repo.permission_user_groups():
576 if p.permission in write_plus:
576 if p.permission in write_plus:
577 user_group_write_permissions[p.users_group_id] = p
577 user_group_write_permissions[p.users_group_id] = p
578 return user_group_write_permissions
578 return user_group_write_permissions
579
579
580 def trigger_permission_flush(self, affected_user_ids):
580 def trigger_permission_flush(self, affected_user_ids=None):
581 affected_user_ids or User.get_all_user_ids()
581 events.trigger(events.UserPermissionsChange(affected_user_ids))
582 events.trigger(events.UserPermissionsChange(affected_user_ids))
582
583
583 def flush_user_permission_caches(self, changes, affected_user_ids=None):
584 def flush_user_permission_caches(self, changes, affected_user_ids=None):
584 affected_user_ids = affected_user_ids or []
585 affected_user_ids = affected_user_ids or []
585
586
586 for change in changes['added'] + changes['updated'] + changes['deleted']:
587 for change in changes['added'] + changes['updated'] + changes['deleted']:
587 if change['type'] == 'user':
588 if change['type'] == 'user':
588 affected_user_ids.append(change['id'])
589 affected_user_ids.append(change['id'])
589 if change['type'] == 'user_group':
590 if change['type'] == 'user_group':
590 user_group = UserGroup.get(safe_int(change['id']))
591 user_group = UserGroup.get(safe_int(change['id']))
591 if user_group:
592 if user_group:
592 group_members_ids = [x.user_id for x in user_group.members]
593 group_members_ids = [x.user_id for x in user_group.members]
593 affected_user_ids.extend(group_members_ids)
594 affected_user_ids.extend(group_members_ids)
594
595
595 self.trigger_permission_flush(affected_user_ids)
596 self.trigger_permission_flush(affected_user_ids)
596
597
597 return affected_user_ids
598 return affected_user_ids
General Comments 0
You need to be logged in to leave comments. Login now