##// END OF EJS Templates
settings: Delete obsolete code related to the rebase-merge lab settings.
Martin Bornhold -
r364:c7282205 default
parent child Browse files
Show More
@@ -1,813 +1,806 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 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 """
22 """
23 settings controller for rhodecode admin
23 settings controller for rhodecode admin
24 """
24 """
25
25
26 import collections
26 import collections
27 import logging
27 import logging
28 import urllib2
28 import urllib2
29
29
30 import datetime
30 import datetime
31 import formencode
31 import formencode
32 from formencode import htmlfill
32 from formencode import htmlfill
33 import packaging.version
33 import packaging.version
34 from pylons import request, tmpl_context as c, url, config
34 from pylons import request, tmpl_context as c, url, config
35 from pylons.controllers.util import redirect
35 from pylons.controllers.util import redirect
36 from pylons.i18n.translation import _, lazy_ugettext
36 from pylons.i18n.translation import _, lazy_ugettext
37 from webob.exc import HTTPBadRequest
37 from webob.exc import HTTPBadRequest
38
38
39 import rhodecode
39 import rhodecode
40 from rhodecode.admin.navigation import navigation_list
40 from rhodecode.admin.navigation import navigation_list
41 from rhodecode.lib import auth
41 from rhodecode.lib import auth
42 from rhodecode.lib import helpers as h
42 from rhodecode.lib import helpers as h
43 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
43 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
44 from rhodecode.lib.base import BaseController, render
44 from rhodecode.lib.base import BaseController, render
45 from rhodecode.lib.celerylib import tasks, run_task
45 from rhodecode.lib.celerylib import tasks, run_task
46 from rhodecode.lib.utils import repo2db_mapper
46 from rhodecode.lib.utils import repo2db_mapper
47 from rhodecode.lib.utils2 import (
47 from rhodecode.lib.utils2 import (
48 str2bool, safe_unicode, AttributeDict, safe_int)
48 str2bool, safe_unicode, AttributeDict, safe_int)
49 from rhodecode.lib.compat import OrderedDict
49 from rhodecode.lib.compat import OrderedDict
50 from rhodecode.lib.ext_json import json
50 from rhodecode.lib.ext_json import json
51 from rhodecode.lib.utils import jsonify
51 from rhodecode.lib.utils import jsonify
52
52
53 from rhodecode.model.db import RhodeCodeUi, Repository
53 from rhodecode.model.db import RhodeCodeUi, Repository
54 from rhodecode.model.forms import ApplicationSettingsForm, \
54 from rhodecode.model.forms import ApplicationSettingsForm, \
55 ApplicationUiSettingsForm, ApplicationVisualisationForm, \
55 ApplicationUiSettingsForm, ApplicationVisualisationForm, \
56 LabsSettingsForm, IssueTrackerPatternsForm
56 LabsSettingsForm, IssueTrackerPatternsForm
57
57
58 from rhodecode.model.scm import ScmModel
58 from rhodecode.model.scm import ScmModel
59 from rhodecode.model.notification import EmailNotificationModel
59 from rhodecode.model.notification import EmailNotificationModel
60 from rhodecode.model.meta import Session
60 from rhodecode.model.meta import Session
61 from rhodecode.model.settings import (
61 from rhodecode.model.settings import (
62 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
62 IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
63 SettingsModel)
63 SettingsModel)
64
64
65 from rhodecode.model.supervisor import SupervisorModel, SUPERVISOR_MASTER
65 from rhodecode.model.supervisor import SupervisorModel, SUPERVISOR_MASTER
66
66
67
67
68 log = logging.getLogger(__name__)
68 log = logging.getLogger(__name__)
69
69
70
70
71 class SettingsController(BaseController):
71 class SettingsController(BaseController):
72 """REST Controller styled on the Atom Publishing Protocol"""
72 """REST Controller styled on the Atom Publishing Protocol"""
73 # To properly map this controller, ensure your config/routing.py
73 # To properly map this controller, ensure your config/routing.py
74 # file has a resource setup:
74 # file has a resource setup:
75 # map.resource('setting', 'settings', controller='admin/settings',
75 # map.resource('setting', 'settings', controller='admin/settings',
76 # path_prefix='/admin', name_prefix='admin_')
76 # path_prefix='/admin', name_prefix='admin_')
77
77
78 @LoginRequired()
78 @LoginRequired()
79 def __before__(self):
79 def __before__(self):
80 super(SettingsController, self).__before__()
80 super(SettingsController, self).__before__()
81 c.labs_active = str2bool(
81 c.labs_active = str2bool(
82 rhodecode.CONFIG.get('labs_settings_active', 'false'))
82 rhodecode.CONFIG.get('labs_settings_active', 'false'))
83 c.navlist = navigation_list(request)
83 c.navlist = navigation_list(request)
84
84
85 def _get_hg_ui_settings(self):
85 def _get_hg_ui_settings(self):
86 ret = RhodeCodeUi.query().all()
86 ret = RhodeCodeUi.query().all()
87
87
88 if not ret:
88 if not ret:
89 raise Exception('Could not get application ui settings !')
89 raise Exception('Could not get application ui settings !')
90 settings = {}
90 settings = {}
91 for each in ret:
91 for each in ret:
92 k = each.ui_key
92 k = each.ui_key
93 v = each.ui_value
93 v = each.ui_value
94 if k == '/':
94 if k == '/':
95 k = 'root_path'
95 k = 'root_path'
96
96
97 if k in ['push_ssl', 'publish']:
97 if k in ['push_ssl', 'publish']:
98 v = str2bool(v)
98 v = str2bool(v)
99
99
100 if k.find('.') != -1:
100 if k.find('.') != -1:
101 k = k.replace('.', '_')
101 k = k.replace('.', '_')
102
102
103 if each.ui_section in ['hooks', 'extensions']:
103 if each.ui_section in ['hooks', 'extensions']:
104 v = each.ui_active
104 v = each.ui_active
105
105
106 settings[each.ui_section + '_' + k] = v
106 settings[each.ui_section + '_' + k] = v
107 return settings
107 return settings
108
108
109 @HasPermissionAllDecorator('hg.admin')
109 @HasPermissionAllDecorator('hg.admin')
110 @auth.CSRFRequired()
110 @auth.CSRFRequired()
111 @jsonify
111 @jsonify
112 def delete_svn_pattern(self):
112 def delete_svn_pattern(self):
113 if not request.is_xhr:
113 if not request.is_xhr:
114 raise HTTPBadRequest()
114 raise HTTPBadRequest()
115
115
116 delete_pattern_id = request.POST.get('delete_svn_pattern')
116 delete_pattern_id = request.POST.get('delete_svn_pattern')
117 model = VcsSettingsModel()
117 model = VcsSettingsModel()
118 try:
118 try:
119 model.delete_global_svn_pattern(delete_pattern_id)
119 model.delete_global_svn_pattern(delete_pattern_id)
120 except SettingNotFound:
120 except SettingNotFound:
121 raise HTTPBadRequest()
121 raise HTTPBadRequest()
122
122
123 Session().commit()
123 Session().commit()
124 return True
124 return True
125
125
126 @HasPermissionAllDecorator('hg.admin')
126 @HasPermissionAllDecorator('hg.admin')
127 @auth.CSRFRequired()
127 @auth.CSRFRequired()
128 def settings_vcs_update(self):
128 def settings_vcs_update(self):
129 """POST /admin/settings: All items in the collection"""
129 """POST /admin/settings: All items in the collection"""
130 # url('admin_settings_vcs')
130 # url('admin_settings_vcs')
131 c.active = 'vcs'
131 c.active = 'vcs'
132
132
133 model = VcsSettingsModel()
133 model = VcsSettingsModel()
134 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
134 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
135 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
135 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
136
136
137 application_form = ApplicationUiSettingsForm()()
137 application_form = ApplicationUiSettingsForm()()
138 try:
138 try:
139 form_result = application_form.to_python(dict(request.POST))
139 form_result = application_form.to_python(dict(request.POST))
140 except formencode.Invalid as errors:
140 except formencode.Invalid as errors:
141 h.flash(
141 h.flash(
142 _("Some form inputs contain invalid data."),
142 _("Some form inputs contain invalid data."),
143 category='error')
143 category='error')
144 return htmlfill.render(
144 return htmlfill.render(
145 render('admin/settings/settings.html'),
145 render('admin/settings/settings.html'),
146 defaults=errors.value,
146 defaults=errors.value,
147 errors=errors.error_dict or {},
147 errors=errors.error_dict or {},
148 prefix_error=False,
148 prefix_error=False,
149 encoding="UTF-8",
149 encoding="UTF-8",
150 force_defaults=False
150 force_defaults=False
151 )
151 )
152
152
153 try:
153 try:
154 model.update_global_ssl_setting(form_result['web_push_ssl'])
154 model.update_global_ssl_setting(form_result['web_push_ssl'])
155 if c.visual.allow_repo_location_change:
155 if c.visual.allow_repo_location_change:
156 model.update_global_path_setting(
156 model.update_global_path_setting(
157 form_result['paths_root_path'])
157 form_result['paths_root_path'])
158 model.update_global_hook_settings(form_result)
158 model.update_global_hook_settings(form_result)
159 model.create_global_svn_settings(form_result)
159 model.create_global_svn_settings(form_result)
160 model.create_or_update_global_hg_settings(form_result)
160 model.create_or_update_global_hg_settings(form_result)
161 model.create_or_update_global_pr_settings(form_result)
161 model.create_or_update_global_pr_settings(form_result)
162 except Exception:
162 except Exception:
163 log.exception("Exception while updating settings")
163 log.exception("Exception while updating settings")
164 h.flash(_('Error occurred during updating '
164 h.flash(_('Error occurred during updating '
165 'application settings'), category='error')
165 'application settings'), category='error')
166 else:
166 else:
167 Session().commit()
167 Session().commit()
168 h.flash(_('Updated VCS settings'), category='success')
168 h.flash(_('Updated VCS settings'), category='success')
169 return redirect(url('admin_settings_vcs'))
169 return redirect(url('admin_settings_vcs'))
170
170
171 return htmlfill.render(
171 return htmlfill.render(
172 render('admin/settings/settings.html'),
172 render('admin/settings/settings.html'),
173 defaults=self._form_defaults(),
173 defaults=self._form_defaults(),
174 encoding="UTF-8",
174 encoding="UTF-8",
175 force_defaults=False)
175 force_defaults=False)
176
176
177 @HasPermissionAllDecorator('hg.admin')
177 @HasPermissionAllDecorator('hg.admin')
178 def settings_vcs(self):
178 def settings_vcs(self):
179 """GET /admin/settings: All items in the collection"""
179 """GET /admin/settings: All items in the collection"""
180 # url('admin_settings_vcs')
180 # url('admin_settings_vcs')
181 c.active = 'vcs'
181 c.active = 'vcs'
182 model = VcsSettingsModel()
182 model = VcsSettingsModel()
183 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
183 c.svn_branch_patterns = model.get_global_svn_branch_patterns()
184 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
184 c.svn_tag_patterns = model.get_global_svn_tag_patterns()
185
185
186 return htmlfill.render(
186 return htmlfill.render(
187 render('admin/settings/settings.html'),
187 render('admin/settings/settings.html'),
188 defaults=self._form_defaults(),
188 defaults=self._form_defaults(),
189 encoding="UTF-8",
189 encoding="UTF-8",
190 force_defaults=False)
190 force_defaults=False)
191
191
192 @HasPermissionAllDecorator('hg.admin')
192 @HasPermissionAllDecorator('hg.admin')
193 @auth.CSRFRequired()
193 @auth.CSRFRequired()
194 def settings_mapping_update(self):
194 def settings_mapping_update(self):
195 """POST /admin/settings/mapping: All items in the collection"""
195 """POST /admin/settings/mapping: All items in the collection"""
196 # url('admin_settings_mapping')
196 # url('admin_settings_mapping')
197 c.active = 'mapping'
197 c.active = 'mapping'
198 rm_obsolete = request.POST.get('destroy', False)
198 rm_obsolete = request.POST.get('destroy', False)
199 invalidate_cache = request.POST.get('invalidate', False)
199 invalidate_cache = request.POST.get('invalidate', False)
200 log.debug(
200 log.debug(
201 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
201 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
202
202
203 if invalidate_cache:
203 if invalidate_cache:
204 log.debug('invalidating all repositories cache')
204 log.debug('invalidating all repositories cache')
205 for repo in Repository.get_all():
205 for repo in Repository.get_all():
206 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
206 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
207
207
208 filesystem_repos = ScmModel().repo_scan()
208 filesystem_repos = ScmModel().repo_scan()
209 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
209 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
210 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
210 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
211 h.flash(_('Repositories successfully '
211 h.flash(_('Repositories successfully '
212 'rescanned added: %s ; removed: %s') %
212 'rescanned added: %s ; removed: %s') %
213 (_repr(added), _repr(removed)),
213 (_repr(added), _repr(removed)),
214 category='success')
214 category='success')
215 return redirect(url('admin_settings_mapping'))
215 return redirect(url('admin_settings_mapping'))
216
216
217 @HasPermissionAllDecorator('hg.admin')
217 @HasPermissionAllDecorator('hg.admin')
218 def settings_mapping(self):
218 def settings_mapping(self):
219 """GET /admin/settings/mapping: All items in the collection"""
219 """GET /admin/settings/mapping: All items in the collection"""
220 # url('admin_settings_mapping')
220 # url('admin_settings_mapping')
221 c.active = 'mapping'
221 c.active = 'mapping'
222
222
223 return htmlfill.render(
223 return htmlfill.render(
224 render('admin/settings/settings.html'),
224 render('admin/settings/settings.html'),
225 defaults=self._form_defaults(),
225 defaults=self._form_defaults(),
226 encoding="UTF-8",
226 encoding="UTF-8",
227 force_defaults=False)
227 force_defaults=False)
228
228
229 @HasPermissionAllDecorator('hg.admin')
229 @HasPermissionAllDecorator('hg.admin')
230 @auth.CSRFRequired()
230 @auth.CSRFRequired()
231 def settings_global_update(self):
231 def settings_global_update(self):
232 """POST /admin/settings/global: All items in the collection"""
232 """POST /admin/settings/global: All items in the collection"""
233 # url('admin_settings_global')
233 # url('admin_settings_global')
234 c.active = 'global'
234 c.active = 'global'
235 application_form = ApplicationSettingsForm()()
235 application_form = ApplicationSettingsForm()()
236 try:
236 try:
237 form_result = application_form.to_python(dict(request.POST))
237 form_result = application_form.to_python(dict(request.POST))
238 except formencode.Invalid as errors:
238 except formencode.Invalid as errors:
239 return htmlfill.render(
239 return htmlfill.render(
240 render('admin/settings/settings.html'),
240 render('admin/settings/settings.html'),
241 defaults=errors.value,
241 defaults=errors.value,
242 errors=errors.error_dict or {},
242 errors=errors.error_dict or {},
243 prefix_error=False,
243 prefix_error=False,
244 encoding="UTF-8",
244 encoding="UTF-8",
245 force_defaults=False)
245 force_defaults=False)
246
246
247 try:
247 try:
248 settings = [
248 settings = [
249 ('title', 'rhodecode_title'),
249 ('title', 'rhodecode_title'),
250 ('realm', 'rhodecode_realm'),
250 ('realm', 'rhodecode_realm'),
251 ('pre_code', 'rhodecode_pre_code'),
251 ('pre_code', 'rhodecode_pre_code'),
252 ('post_code', 'rhodecode_post_code'),
252 ('post_code', 'rhodecode_post_code'),
253 ('captcha_public_key', 'rhodecode_captcha_public_key'),
253 ('captcha_public_key', 'rhodecode_captcha_public_key'),
254 ('captcha_private_key', 'rhodecode_captcha_private_key'),
254 ('captcha_private_key', 'rhodecode_captcha_private_key'),
255 ]
255 ]
256 for setting, form_key in settings:
256 for setting, form_key in settings:
257 sett = SettingsModel().create_or_update_setting(
257 sett = SettingsModel().create_or_update_setting(
258 setting, form_result[form_key])
258 setting, form_result[form_key])
259 Session().add(sett)
259 Session().add(sett)
260
260
261 Session().commit()
261 Session().commit()
262 SettingsModel().invalidate_settings_cache()
262 SettingsModel().invalidate_settings_cache()
263 h.flash(_('Updated application settings'), category='success')
263 h.flash(_('Updated application settings'), category='success')
264 except Exception:
264 except Exception:
265 log.exception("Exception while updating application settings")
265 log.exception("Exception while updating application settings")
266 h.flash(
266 h.flash(
267 _('Error occurred during updating application settings'),
267 _('Error occurred during updating application settings'),
268 category='error')
268 category='error')
269
269
270 return redirect(url('admin_settings_global'))
270 return redirect(url('admin_settings_global'))
271
271
272 @HasPermissionAllDecorator('hg.admin')
272 @HasPermissionAllDecorator('hg.admin')
273 def settings_global(self):
273 def settings_global(self):
274 """GET /admin/settings/global: All items in the collection"""
274 """GET /admin/settings/global: All items in the collection"""
275 # url('admin_settings_global')
275 # url('admin_settings_global')
276 c.active = 'global'
276 c.active = 'global'
277
277
278 return htmlfill.render(
278 return htmlfill.render(
279 render('admin/settings/settings.html'),
279 render('admin/settings/settings.html'),
280 defaults=self._form_defaults(),
280 defaults=self._form_defaults(),
281 encoding="UTF-8",
281 encoding="UTF-8",
282 force_defaults=False)
282 force_defaults=False)
283
283
284 @HasPermissionAllDecorator('hg.admin')
284 @HasPermissionAllDecorator('hg.admin')
285 @auth.CSRFRequired()
285 @auth.CSRFRequired()
286 def settings_visual_update(self):
286 def settings_visual_update(self):
287 """POST /admin/settings/visual: All items in the collection"""
287 """POST /admin/settings/visual: All items in the collection"""
288 # url('admin_settings_visual')
288 # url('admin_settings_visual')
289 c.active = 'visual'
289 c.active = 'visual'
290 application_form = ApplicationVisualisationForm()()
290 application_form = ApplicationVisualisationForm()()
291 try:
291 try:
292 form_result = application_form.to_python(dict(request.POST))
292 form_result = application_form.to_python(dict(request.POST))
293 except formencode.Invalid as errors:
293 except formencode.Invalid as errors:
294 return htmlfill.render(
294 return htmlfill.render(
295 render('admin/settings/settings.html'),
295 render('admin/settings/settings.html'),
296 defaults=errors.value,
296 defaults=errors.value,
297 errors=errors.error_dict or {},
297 errors=errors.error_dict or {},
298 prefix_error=False,
298 prefix_error=False,
299 encoding="UTF-8",
299 encoding="UTF-8",
300 force_defaults=False
300 force_defaults=False
301 )
301 )
302
302
303 try:
303 try:
304 settings = [
304 settings = [
305 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
305 ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
306 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
306 ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
307 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
307 ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
308 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
308 ('repository_fields', 'rhodecode_repository_fields', 'bool'),
309 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
309 ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
310 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
310 ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
311 ('show_version', 'rhodecode_show_version', 'bool'),
311 ('show_version', 'rhodecode_show_version', 'bool'),
312 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
312 ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
313 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
313 ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
314 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
314 ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
315 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
315 ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
316 ('support_url', 'rhodecode_support_url', 'unicode'),
316 ('support_url', 'rhodecode_support_url', 'unicode'),
317 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
317 ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
318 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
318 ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
319 ]
319 ]
320 for setting, form_key, type_ in settings:
320 for setting, form_key, type_ in settings:
321 sett = SettingsModel().create_or_update_setting(
321 sett = SettingsModel().create_or_update_setting(
322 setting, form_result[form_key], type_)
322 setting, form_result[form_key], type_)
323 Session().add(sett)
323 Session().add(sett)
324
324
325 Session().commit()
325 Session().commit()
326 SettingsModel().invalidate_settings_cache()
326 SettingsModel().invalidate_settings_cache()
327 h.flash(_('Updated visualisation settings'), category='success')
327 h.flash(_('Updated visualisation settings'), category='success')
328 except Exception:
328 except Exception:
329 log.exception("Exception updating visualization settings")
329 log.exception("Exception updating visualization settings")
330 h.flash(_('Error occurred during updating '
330 h.flash(_('Error occurred during updating '
331 'visualisation settings'),
331 'visualisation settings'),
332 category='error')
332 category='error')
333
333
334 return redirect(url('admin_settings_visual'))
334 return redirect(url('admin_settings_visual'))
335
335
336 @HasPermissionAllDecorator('hg.admin')
336 @HasPermissionAllDecorator('hg.admin')
337 def settings_visual(self):
337 def settings_visual(self):
338 """GET /admin/settings/visual: All items in the collection"""
338 """GET /admin/settings/visual: All items in the collection"""
339 # url('admin_settings_visual')
339 # url('admin_settings_visual')
340 c.active = 'visual'
340 c.active = 'visual'
341
341
342 return htmlfill.render(
342 return htmlfill.render(
343 render('admin/settings/settings.html'),
343 render('admin/settings/settings.html'),
344 defaults=self._form_defaults(),
344 defaults=self._form_defaults(),
345 encoding="UTF-8",
345 encoding="UTF-8",
346 force_defaults=False)
346 force_defaults=False)
347
347
348 @HasPermissionAllDecorator('hg.admin')
348 @HasPermissionAllDecorator('hg.admin')
349 @auth.CSRFRequired()
349 @auth.CSRFRequired()
350 def settings_issuetracker_test(self):
350 def settings_issuetracker_test(self):
351 if request.is_xhr:
351 if request.is_xhr:
352 return h.urlify_commit_message(
352 return h.urlify_commit_message(
353 request.POST.get('test_text', ''),
353 request.POST.get('test_text', ''),
354 'repo_group/test_repo1')
354 'repo_group/test_repo1')
355 else:
355 else:
356 raise HTTPBadRequest()
356 raise HTTPBadRequest()
357
357
358 @HasPermissionAllDecorator('hg.admin')
358 @HasPermissionAllDecorator('hg.admin')
359 @auth.CSRFRequired()
359 @auth.CSRFRequired()
360 def settings_issuetracker_delete(self):
360 def settings_issuetracker_delete(self):
361 uid = request.POST.get('uid')
361 uid = request.POST.get('uid')
362 IssueTrackerSettingsModel().delete_entries(uid)
362 IssueTrackerSettingsModel().delete_entries(uid)
363 h.flash(_('Removed issue tracker entry'), category='success')
363 h.flash(_('Removed issue tracker entry'), category='success')
364 return redirect(url('admin_settings_issuetracker'))
364 return redirect(url('admin_settings_issuetracker'))
365
365
366 @HasPermissionAllDecorator('hg.admin')
366 @HasPermissionAllDecorator('hg.admin')
367 def settings_issuetracker(self):
367 def settings_issuetracker(self):
368 """GET /admin/settings/issue-tracker: All items in the collection"""
368 """GET /admin/settings/issue-tracker: All items in the collection"""
369 # url('admin_settings_issuetracker')
369 # url('admin_settings_issuetracker')
370 c.active = 'issuetracker'
370 c.active = 'issuetracker'
371 defaults = SettingsModel().get_all_settings()
371 defaults = SettingsModel().get_all_settings()
372
372
373 entry_key = 'rhodecode_issuetracker_pat_'
373 entry_key = 'rhodecode_issuetracker_pat_'
374
374
375 c.issuetracker_entries = {}
375 c.issuetracker_entries = {}
376 for k, v in defaults.items():
376 for k, v in defaults.items():
377 if k.startswith(entry_key):
377 if k.startswith(entry_key):
378 uid = k[len(entry_key):]
378 uid = k[len(entry_key):]
379 c.issuetracker_entries[uid] = None
379 c.issuetracker_entries[uid] = None
380
380
381 for uid in c.issuetracker_entries:
381 for uid in c.issuetracker_entries:
382 c.issuetracker_entries[uid] = AttributeDict({
382 c.issuetracker_entries[uid] = AttributeDict({
383 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
383 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
384 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
384 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
385 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
385 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
386 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
386 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
387 })
387 })
388
388
389 return render('admin/settings/settings.html')
389 return render('admin/settings/settings.html')
390
390
391 @HasPermissionAllDecorator('hg.admin')
391 @HasPermissionAllDecorator('hg.admin')
392 @auth.CSRFRequired()
392 @auth.CSRFRequired()
393 def settings_issuetracker_save(self):
393 def settings_issuetracker_save(self):
394 settings_model = IssueTrackerSettingsModel()
394 settings_model = IssueTrackerSettingsModel()
395
395
396 form = IssueTrackerPatternsForm()().to_python(request.POST)
396 form = IssueTrackerPatternsForm()().to_python(request.POST)
397 for uid in form['delete_patterns']:
397 for uid in form['delete_patterns']:
398 settings_model.delete_entries(uid)
398 settings_model.delete_entries(uid)
399
399
400 for pattern in form['patterns']:
400 for pattern in form['patterns']:
401 for setting, value, type_ in pattern:
401 for setting, value, type_ in pattern:
402 sett = settings_model.create_or_update_setting(
402 sett = settings_model.create_or_update_setting(
403 setting, value, type_)
403 setting, value, type_)
404 Session().add(sett)
404 Session().add(sett)
405
405
406 Session().commit()
406 Session().commit()
407
407
408 SettingsModel().invalidate_settings_cache()
408 SettingsModel().invalidate_settings_cache()
409 h.flash(_('Updated issue tracker entries'), category='success')
409 h.flash(_('Updated issue tracker entries'), category='success')
410 return redirect(url('admin_settings_issuetracker'))
410 return redirect(url('admin_settings_issuetracker'))
411
411
412 @HasPermissionAllDecorator('hg.admin')
412 @HasPermissionAllDecorator('hg.admin')
413 @auth.CSRFRequired()
413 @auth.CSRFRequired()
414 def settings_email_update(self):
414 def settings_email_update(self):
415 """POST /admin/settings/email: All items in the collection"""
415 """POST /admin/settings/email: All items in the collection"""
416 # url('admin_settings_email')
416 # url('admin_settings_email')
417 c.active = 'email'
417 c.active = 'email'
418
418
419 test_email = request.POST.get('test_email')
419 test_email = request.POST.get('test_email')
420
420
421 if not test_email:
421 if not test_email:
422 h.flash(_('Please enter email address'), category='error')
422 h.flash(_('Please enter email address'), category='error')
423 return redirect(url('admin_settings_email'))
423 return redirect(url('admin_settings_email'))
424
424
425 email_kwargs = {
425 email_kwargs = {
426 'date': datetime.datetime.now(),
426 'date': datetime.datetime.now(),
427 'user': c.rhodecode_user,
427 'user': c.rhodecode_user,
428 'rhodecode_version': c.rhodecode_version
428 'rhodecode_version': c.rhodecode_version
429 }
429 }
430
430
431 (subject, headers, email_body,
431 (subject, headers, email_body,
432 email_body_plaintext) = EmailNotificationModel().render_email(
432 email_body_plaintext) = EmailNotificationModel().render_email(
433 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
433 EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
434
434
435 recipients = [test_email] if test_email else None
435 recipients = [test_email] if test_email else None
436
436
437 run_task(tasks.send_email, recipients, subject,
437 run_task(tasks.send_email, recipients, subject,
438 email_body_plaintext, email_body)
438 email_body_plaintext, email_body)
439
439
440 h.flash(_('Send email task created'), category='success')
440 h.flash(_('Send email task created'), category='success')
441 return redirect(url('admin_settings_email'))
441 return redirect(url('admin_settings_email'))
442
442
443 @HasPermissionAllDecorator('hg.admin')
443 @HasPermissionAllDecorator('hg.admin')
444 def settings_email(self):
444 def settings_email(self):
445 """GET /admin/settings/email: All items in the collection"""
445 """GET /admin/settings/email: All items in the collection"""
446 # url('admin_settings_email')
446 # url('admin_settings_email')
447 c.active = 'email'
447 c.active = 'email'
448 c.rhodecode_ini = rhodecode.CONFIG
448 c.rhodecode_ini = rhodecode.CONFIG
449
449
450 return htmlfill.render(
450 return htmlfill.render(
451 render('admin/settings/settings.html'),
451 render('admin/settings/settings.html'),
452 defaults=self._form_defaults(),
452 defaults=self._form_defaults(),
453 encoding="UTF-8",
453 encoding="UTF-8",
454 force_defaults=False)
454 force_defaults=False)
455
455
456 @HasPermissionAllDecorator('hg.admin')
456 @HasPermissionAllDecorator('hg.admin')
457 @auth.CSRFRequired()
457 @auth.CSRFRequired()
458 def settings_hooks_update(self):
458 def settings_hooks_update(self):
459 """POST or DELETE /admin/settings/hooks: All items in the collection"""
459 """POST or DELETE /admin/settings/hooks: All items in the collection"""
460 # url('admin_settings_hooks')
460 # url('admin_settings_hooks')
461 c.active = 'hooks'
461 c.active = 'hooks'
462 if c.visual.allow_custom_hooks_settings:
462 if c.visual.allow_custom_hooks_settings:
463 ui_key = request.POST.get('new_hook_ui_key')
463 ui_key = request.POST.get('new_hook_ui_key')
464 ui_value = request.POST.get('new_hook_ui_value')
464 ui_value = request.POST.get('new_hook_ui_value')
465
465
466 hook_id = request.POST.get('hook_id')
466 hook_id = request.POST.get('hook_id')
467 new_hook = False
467 new_hook = False
468
468
469 model = SettingsModel()
469 model = SettingsModel()
470 try:
470 try:
471 if ui_value and ui_key:
471 if ui_value and ui_key:
472 model.create_or_update_hook(ui_key, ui_value)
472 model.create_or_update_hook(ui_key, ui_value)
473 h.flash(_('Added new hook'), category='success')
473 h.flash(_('Added new hook'), category='success')
474 new_hook = True
474 new_hook = True
475 elif hook_id:
475 elif hook_id:
476 RhodeCodeUi.delete(hook_id)
476 RhodeCodeUi.delete(hook_id)
477 Session().commit()
477 Session().commit()
478
478
479 # check for edits
479 # check for edits
480 update = False
480 update = False
481 _d = request.POST.dict_of_lists()
481 _d = request.POST.dict_of_lists()
482 for k, v in zip(_d.get('hook_ui_key', []),
482 for k, v in zip(_d.get('hook_ui_key', []),
483 _d.get('hook_ui_value_new', [])):
483 _d.get('hook_ui_value_new', [])):
484 model.create_or_update_hook(k, v)
484 model.create_or_update_hook(k, v)
485 update = True
485 update = True
486
486
487 if update and not new_hook:
487 if update and not new_hook:
488 h.flash(_('Updated hooks'), category='success')
488 h.flash(_('Updated hooks'), category='success')
489 Session().commit()
489 Session().commit()
490 except Exception:
490 except Exception:
491 log.exception("Exception during hook creation")
491 log.exception("Exception during hook creation")
492 h.flash(_('Error occurred during hook creation'),
492 h.flash(_('Error occurred during hook creation'),
493 category='error')
493 category='error')
494
494
495 return redirect(url('admin_settings_hooks'))
495 return redirect(url('admin_settings_hooks'))
496
496
497 @HasPermissionAllDecorator('hg.admin')
497 @HasPermissionAllDecorator('hg.admin')
498 def settings_hooks(self):
498 def settings_hooks(self):
499 """GET /admin/settings/hooks: All items in the collection"""
499 """GET /admin/settings/hooks: All items in the collection"""
500 # url('admin_settings_hooks')
500 # url('admin_settings_hooks')
501 c.active = 'hooks'
501 c.active = 'hooks'
502
502
503 model = SettingsModel()
503 model = SettingsModel()
504 c.hooks = model.get_builtin_hooks()
504 c.hooks = model.get_builtin_hooks()
505 c.custom_hooks = model.get_custom_hooks()
505 c.custom_hooks = model.get_custom_hooks()
506
506
507 return htmlfill.render(
507 return htmlfill.render(
508 render('admin/settings/settings.html'),
508 render('admin/settings/settings.html'),
509 defaults=self._form_defaults(),
509 defaults=self._form_defaults(),
510 encoding="UTF-8",
510 encoding="UTF-8",
511 force_defaults=False)
511 force_defaults=False)
512
512
513 @HasPermissionAllDecorator('hg.admin')
513 @HasPermissionAllDecorator('hg.admin')
514 def settings_search(self):
514 def settings_search(self):
515 """GET /admin/settings/search: All items in the collection"""
515 """GET /admin/settings/search: All items in the collection"""
516 # url('admin_settings_search')
516 # url('admin_settings_search')
517 c.active = 'search'
517 c.active = 'search'
518
518
519 from rhodecode.lib.index import searcher_from_config
519 from rhodecode.lib.index import searcher_from_config
520 searcher = searcher_from_config(config)
520 searcher = searcher_from_config(config)
521 c.statistics = searcher.statistics()
521 c.statistics = searcher.statistics()
522
522
523 return render('admin/settings/settings.html')
523 return render('admin/settings/settings.html')
524
524
525 @HasPermissionAllDecorator('hg.admin')
525 @HasPermissionAllDecorator('hg.admin')
526 def settings_system(self):
526 def settings_system(self):
527 """GET /admin/settings/system: All items in the collection"""
527 """GET /admin/settings/system: All items in the collection"""
528 # url('admin_settings_system')
528 # url('admin_settings_system')
529 snapshot = str2bool(request.GET.get('snapshot'))
529 snapshot = str2bool(request.GET.get('snapshot'))
530 c.active = 'system'
530 c.active = 'system'
531
531
532 defaults = self._form_defaults()
532 defaults = self._form_defaults()
533 c.rhodecode_ini = rhodecode.CONFIG
533 c.rhodecode_ini = rhodecode.CONFIG
534 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
534 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
535 server_info = ScmModel().get_server_info(request.environ)
535 server_info = ScmModel().get_server_info(request.environ)
536 for key, val in server_info.iteritems():
536 for key, val in server_info.iteritems():
537 setattr(c, key, val)
537 setattr(c, key, val)
538
538
539 if c.disk['percent'] > 90:
539 if c.disk['percent'] > 90:
540 h.flash(h.literal(_(
540 h.flash(h.literal(_(
541 'Critical: your disk space is very low <b>%s%%</b> used' %
541 'Critical: your disk space is very low <b>%s%%</b> used' %
542 c.disk['percent'])), 'error')
542 c.disk['percent'])), 'error')
543 elif c.disk['percent'] > 70:
543 elif c.disk['percent'] > 70:
544 h.flash(h.literal(_(
544 h.flash(h.literal(_(
545 'Warning: your disk space is running low <b>%s%%</b> used' %
545 'Warning: your disk space is running low <b>%s%%</b> used' %
546 c.disk['percent'])), 'warning')
546 c.disk['percent'])), 'warning')
547
547
548 try:
548 try:
549 c.uptime_age = h._age(
549 c.uptime_age = h._age(
550 h.time_to_datetime(c.boot_time), False, show_suffix=False)
550 h.time_to_datetime(c.boot_time), False, show_suffix=False)
551 except TypeError:
551 except TypeError:
552 c.uptime_age = c.boot_time
552 c.uptime_age = c.boot_time
553
553
554 try:
554 try:
555 c.system_memory = '%s/%s, %s%% (%s%%) used%s' % (
555 c.system_memory = '%s/%s, %s%% (%s%%) used%s' % (
556 h.format_byte_size_binary(c.memory['used']),
556 h.format_byte_size_binary(c.memory['used']),
557 h.format_byte_size_binary(c.memory['total']),
557 h.format_byte_size_binary(c.memory['total']),
558 c.memory['percent2'],
558 c.memory['percent2'],
559 c.memory['percent'],
559 c.memory['percent'],
560 ' %s' % c.memory['error'] if 'error' in c.memory else '')
560 ' %s' % c.memory['error'] if 'error' in c.memory else '')
561 except TypeError:
561 except TypeError:
562 c.system_memory = 'NOT AVAILABLE'
562 c.system_memory = 'NOT AVAILABLE'
563
563
564 rhodecode_ini_safe = rhodecode.CONFIG.copy()
564 rhodecode_ini_safe = rhodecode.CONFIG.copy()
565 blacklist = [
565 blacklist = [
566 'rhodecode_license_key',
566 'rhodecode_license_key',
567 'routes.map',
567 'routes.map',
568 'pylons.h',
568 'pylons.h',
569 'pylons.app_globals',
569 'pylons.app_globals',
570 'pylons.environ_config',
570 'pylons.environ_config',
571 'sqlalchemy.db1.url',
571 'sqlalchemy.db1.url',
572 ('app_conf', 'sqlalchemy.db1.url')
572 ('app_conf', 'sqlalchemy.db1.url')
573 ]
573 ]
574 for k in blacklist:
574 for k in blacklist:
575 if isinstance(k, tuple):
575 if isinstance(k, tuple):
576 section, key = k
576 section, key = k
577 if section in rhodecode_ini_safe:
577 if section in rhodecode_ini_safe:
578 rhodecode_ini_safe[section].pop(key, None)
578 rhodecode_ini_safe[section].pop(key, None)
579 else:
579 else:
580 rhodecode_ini_safe.pop(k, None)
580 rhodecode_ini_safe.pop(k, None)
581
581
582 c.rhodecode_ini_safe = rhodecode_ini_safe
582 c.rhodecode_ini_safe = rhodecode_ini_safe
583
583
584 # TODO: marcink, figure out how to allow only selected users to do this
584 # TODO: marcink, figure out how to allow only selected users to do this
585 c.allowed_to_snapshot = False
585 c.allowed_to_snapshot = False
586
586
587 if snapshot:
587 if snapshot:
588 if c.allowed_to_snapshot:
588 if c.allowed_to_snapshot:
589 return render('admin/settings/settings_system_snapshot.html')
589 return render('admin/settings/settings_system_snapshot.html')
590 else:
590 else:
591 h.flash('You are not allowed to do this', category='warning')
591 h.flash('You are not allowed to do this', category='warning')
592
592
593 return htmlfill.render(
593 return htmlfill.render(
594 render('admin/settings/settings.html'),
594 render('admin/settings/settings.html'),
595 defaults=defaults,
595 defaults=defaults,
596 encoding="UTF-8",
596 encoding="UTF-8",
597 force_defaults=False)
597 force_defaults=False)
598
598
599 @staticmethod
599 @staticmethod
600 def get_update_data(update_url):
600 def get_update_data(update_url):
601 """Return the JSON update data."""
601 """Return the JSON update data."""
602 ver = rhodecode.__version__
602 ver = rhodecode.__version__
603 log.debug('Checking for upgrade on `%s` server', update_url)
603 log.debug('Checking for upgrade on `%s` server', update_url)
604 opener = urllib2.build_opener()
604 opener = urllib2.build_opener()
605 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
605 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
606 response = opener.open(update_url)
606 response = opener.open(update_url)
607 response_data = response.read()
607 response_data = response.read()
608 data = json.loads(response_data)
608 data = json.loads(response_data)
609
609
610 return data
610 return data
611
611
612 @HasPermissionAllDecorator('hg.admin')
612 @HasPermissionAllDecorator('hg.admin')
613 def settings_system_update(self):
613 def settings_system_update(self):
614 """GET /admin/settings/system/updates: All items in the collection"""
614 """GET /admin/settings/system/updates: All items in the collection"""
615 # url('admin_settings_system_update')
615 # url('admin_settings_system_update')
616 defaults = self._form_defaults()
616 defaults = self._form_defaults()
617 update_url = defaults.get('rhodecode_update_url', '')
617 update_url = defaults.get('rhodecode_update_url', '')
618
618
619 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s)
619 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s)
620 try:
620 try:
621 data = self.get_update_data(update_url)
621 data = self.get_update_data(update_url)
622 except urllib2.URLError as e:
622 except urllib2.URLError as e:
623 log.exception("Exception contacting upgrade server")
623 log.exception("Exception contacting upgrade server")
624 return _err('Failed to contact upgrade server: %r' % e)
624 return _err('Failed to contact upgrade server: %r' % e)
625 except ValueError as e:
625 except ValueError as e:
626 log.exception("Bad data sent from update server")
626 log.exception("Bad data sent from update server")
627 return _err('Bad data sent from update server')
627 return _err('Bad data sent from update server')
628
628
629 latest = data['versions'][0]
629 latest = data['versions'][0]
630
630
631 c.update_url = update_url
631 c.update_url = update_url
632 c.latest_data = latest
632 c.latest_data = latest
633 c.latest_ver = latest['version']
633 c.latest_ver = latest['version']
634 c.cur_ver = rhodecode.__version__
634 c.cur_ver = rhodecode.__version__
635 c.should_upgrade = False
635 c.should_upgrade = False
636
636
637 if (packaging.version.Version(c.latest_ver) >
637 if (packaging.version.Version(c.latest_ver) >
638 packaging.version.Version(c.cur_ver)):
638 packaging.version.Version(c.cur_ver)):
639 c.should_upgrade = True
639 c.should_upgrade = True
640 c.important_notices = latest['general']
640 c.important_notices = latest['general']
641
641
642 return render('admin/settings/settings_system_update.html')
642 return render('admin/settings/settings_system_update.html')
643
643
644 @HasPermissionAllDecorator('hg.admin')
644 @HasPermissionAllDecorator('hg.admin')
645 def settings_supervisor(self):
645 def settings_supervisor(self):
646 c.rhodecode_ini = rhodecode.CONFIG
646 c.rhodecode_ini = rhodecode.CONFIG
647 c.active = 'supervisor'
647 c.active = 'supervisor'
648
648
649 c.supervisor_procs = OrderedDict([
649 c.supervisor_procs = OrderedDict([
650 (SUPERVISOR_MASTER, {}),
650 (SUPERVISOR_MASTER, {}),
651 ])
651 ])
652
652
653 c.log_size = 10240
653 c.log_size = 10240
654 supervisor = SupervisorModel()
654 supervisor = SupervisorModel()
655
655
656 _connection = supervisor.get_connection(
656 _connection = supervisor.get_connection(
657 c.rhodecode_ini.get('supervisor.uri'))
657 c.rhodecode_ini.get('supervisor.uri'))
658 c.connection_error = None
658 c.connection_error = None
659 try:
659 try:
660 _connection.supervisor.getAllProcessInfo()
660 _connection.supervisor.getAllProcessInfo()
661 except Exception as e:
661 except Exception as e:
662 c.connection_error = str(e)
662 c.connection_error = str(e)
663 log.exception("Exception reading supervisor data")
663 log.exception("Exception reading supervisor data")
664 return render('admin/settings/settings.html')
664 return render('admin/settings/settings.html')
665
665
666 groupid = c.rhodecode_ini.get('supervisor.group_id')
666 groupid = c.rhodecode_ini.get('supervisor.group_id')
667
667
668 # feed our group processes to the main
668 # feed our group processes to the main
669 for proc in supervisor.get_group_processes(_connection, groupid):
669 for proc in supervisor.get_group_processes(_connection, groupid):
670 c.supervisor_procs[proc['name']] = {}
670 c.supervisor_procs[proc['name']] = {}
671
671
672 for k in c.supervisor_procs.keys():
672 for k in c.supervisor_procs.keys():
673 try:
673 try:
674 # master process info
674 # master process info
675 if k == SUPERVISOR_MASTER:
675 if k == SUPERVISOR_MASTER:
676 _data = supervisor.get_master_state(_connection)
676 _data = supervisor.get_master_state(_connection)
677 _data['name'] = 'supervisor master'
677 _data['name'] = 'supervisor master'
678 _data['description'] = 'pid %s, id: %s, ver: %s' % (
678 _data['description'] = 'pid %s, id: %s, ver: %s' % (
679 _data['pid'], _data['id'], _data['ver'])
679 _data['pid'], _data['id'], _data['ver'])
680 c.supervisor_procs[k] = _data
680 c.supervisor_procs[k] = _data
681 else:
681 else:
682 procid = groupid + ":" + k
682 procid = groupid + ":" + k
683 c.supervisor_procs[k] = supervisor.get_process_info(_connection, procid)
683 c.supervisor_procs[k] = supervisor.get_process_info(_connection, procid)
684 except Exception as e:
684 except Exception as e:
685 log.exception("Exception reading supervisor data")
685 log.exception("Exception reading supervisor data")
686 c.supervisor_procs[k] = {'_rhodecode_error': str(e)}
686 c.supervisor_procs[k] = {'_rhodecode_error': str(e)}
687
687
688 return render('admin/settings/settings.html')
688 return render('admin/settings/settings.html')
689
689
690 @HasPermissionAllDecorator('hg.admin')
690 @HasPermissionAllDecorator('hg.admin')
691 def settings_supervisor_log(self, procid):
691 def settings_supervisor_log(self, procid):
692 import rhodecode
692 import rhodecode
693 c.rhodecode_ini = rhodecode.CONFIG
693 c.rhodecode_ini = rhodecode.CONFIG
694 c.active = 'supervisor_tail'
694 c.active = 'supervisor_tail'
695
695
696 supervisor = SupervisorModel()
696 supervisor = SupervisorModel()
697 _connection = supervisor.get_connection(c.rhodecode_ini.get('supervisor.uri'))
697 _connection = supervisor.get_connection(c.rhodecode_ini.get('supervisor.uri'))
698 groupid = c.rhodecode_ini.get('supervisor.group_id')
698 groupid = c.rhodecode_ini.get('supervisor.group_id')
699 procid = groupid + ":" + procid if procid != SUPERVISOR_MASTER else procid
699 procid = groupid + ":" + procid if procid != SUPERVISOR_MASTER else procid
700
700
701 c.log_size = 10240
701 c.log_size = 10240
702 offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1
702 offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1
703 c.log = supervisor.read_process_log(_connection, procid, offset, 0)
703 c.log = supervisor.read_process_log(_connection, procid, offset, 0)
704
704
705 return render('admin/settings/settings.html')
705 return render('admin/settings/settings.html')
706
706
707 @HasPermissionAllDecorator('hg.admin')
707 @HasPermissionAllDecorator('hg.admin')
708 @auth.CSRFRequired()
708 @auth.CSRFRequired()
709 def settings_labs_update(self):
709 def settings_labs_update(self):
710 """POST /admin/settings/labs: All items in the collection"""
710 """POST /admin/settings/labs: All items in the collection"""
711 # url('admin_settings/labs', method={'POST'})
711 # url('admin_settings/labs', method={'POST'})
712 c.active = 'labs'
712 c.active = 'labs'
713
713
714 application_form = LabsSettingsForm()()
714 application_form = LabsSettingsForm()()
715 try:
715 try:
716 form_result = application_form.to_python(dict(request.POST))
716 form_result = application_form.to_python(dict(request.POST))
717 except formencode.Invalid as errors:
717 except formencode.Invalid as errors:
718 h.flash(
718 h.flash(
719 _('Some form inputs contain invalid data.'),
719 _('Some form inputs contain invalid data.'),
720 category='error')
720 category='error')
721 return htmlfill.render(
721 return htmlfill.render(
722 render('admin/settings/settings.html'),
722 render('admin/settings/settings.html'),
723 defaults=errors.value,
723 defaults=errors.value,
724 errors=errors.error_dict or {},
724 errors=errors.error_dict or {},
725 prefix_error=False,
725 prefix_error=False,
726 encoding='UTF-8',
726 encoding='UTF-8',
727 force_defaults=False
727 force_defaults=False
728 )
728 )
729
729
730 try:
730 try:
731 session = Session()
731 session = Session()
732 for setting in _LAB_SETTINGS:
732 for setting in _LAB_SETTINGS:
733 setting_name = setting.key[len('rhodecode_'):]
733 setting_name = setting.key[len('rhodecode_'):]
734 sett = SettingsModel().create_or_update_setting(
734 sett = SettingsModel().create_or_update_setting(
735 setting_name, form_result[setting.key], setting.type)
735 setting_name, form_result[setting.key], setting.type)
736 session.add(sett)
736 session.add(sett)
737
737
738 except Exception:
738 except Exception:
739 log.exception('Exception while updating lab settings')
739 log.exception('Exception while updating lab settings')
740 h.flash(_('Error occurred during updating labs settings'),
740 h.flash(_('Error occurred during updating labs settings'),
741 category='error')
741 category='error')
742 else:
742 else:
743 Session().commit()
743 Session().commit()
744 SettingsModel().invalidate_settings_cache()
744 SettingsModel().invalidate_settings_cache()
745 h.flash(_('Updated Labs settings'), category='success')
745 h.flash(_('Updated Labs settings'), category='success')
746 return redirect(url('admin_settings_labs'))
746 return redirect(url('admin_settings_labs'))
747
747
748 return htmlfill.render(
748 return htmlfill.render(
749 render('admin/settings/settings.html'),
749 render('admin/settings/settings.html'),
750 defaults=self._form_defaults(),
750 defaults=self._form_defaults(),
751 encoding='UTF-8',
751 encoding='UTF-8',
752 force_defaults=False)
752 force_defaults=False)
753
753
754 @HasPermissionAllDecorator('hg.admin')
754 @HasPermissionAllDecorator('hg.admin')
755 def settings_labs(self):
755 def settings_labs(self):
756 """GET /admin/settings/labs: All items in the collection"""
756 """GET /admin/settings/labs: All items in the collection"""
757 # url('admin_settings_labs')
757 # url('admin_settings_labs')
758 if not c.labs_active:
758 if not c.labs_active:
759 redirect(url('admin_settings'))
759 redirect(url('admin_settings'))
760
760
761 c.active = 'labs'
761 c.active = 'labs'
762 c.lab_settings = _LAB_SETTINGS
762 c.lab_settings = _LAB_SETTINGS
763
763
764 return htmlfill.render(
764 return htmlfill.render(
765 render('admin/settings/settings.html'),
765 render('admin/settings/settings.html'),
766 defaults=self._form_defaults(),
766 defaults=self._form_defaults(),
767 encoding='UTF-8',
767 encoding='UTF-8',
768 force_defaults=False)
768 force_defaults=False)
769
769
770 def _form_defaults(self):
770 def _form_defaults(self):
771 defaults = SettingsModel().get_all_settings()
771 defaults = SettingsModel().get_all_settings()
772 defaults.update(self._get_hg_ui_settings())
772 defaults.update(self._get_hg_ui_settings())
773 defaults.update({
773 defaults.update({
774 'new_svn_branch': '',
774 'new_svn_branch': '',
775 'new_svn_tag': '',
775 'new_svn_tag': '',
776 })
776 })
777 return defaults
777 return defaults
778
778
779
779
780 # :param key: name of the setting including the 'rhodecode_' prefix
780 # :param key: name of the setting including the 'rhodecode_' prefix
781 # :param type: the RhodeCodeSetting type to use.
781 # :param type: the RhodeCodeSetting type to use.
782 # :param group: the i18ned group in which we should dispaly this setting
782 # :param group: the i18ned group in which we should dispaly this setting
783 # :param label: the i18ned label we should display for this setting
783 # :param label: the i18ned label we should display for this setting
784 # :param help: the i18ned help we should dispaly for this setting
784 # :param help: the i18ned help we should dispaly for this setting
785 LabSetting = collections.namedtuple(
785 LabSetting = collections.namedtuple(
786 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
786 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
787
787
788
788
789 # This list has to be kept in sync with the form
789 # This list has to be kept in sync with the form
790 # rhodecode.model.forms.LabsSettingsForm.
790 # rhodecode.model.forms.LabsSettingsForm.
791 _LAB_SETTINGS = [
791 _LAB_SETTINGS = [
792 LabSetting(
792 LabSetting(
793 key='rhodecode_hg_use_rebase_for_merging',
794 type='bool',
795 group=lazy_ugettext('Mercurial server-side merge'),
796 label=lazy_ugettext('Use rebase instead of creating a merge commit when merging via web interface'),
797 help='' # Do not translate the empty string!
798 ),
799 LabSetting(
800 key='rhodecode_proxy_subversion_http_requests',
793 key='rhodecode_proxy_subversion_http_requests',
801 type='bool',
794 type='bool',
802 group=lazy_ugettext('Subversion HTTP Support'),
795 group=lazy_ugettext('Subversion HTTP Support'),
803 label=lazy_ugettext('Proxy subversion HTTP requests'),
796 label=lazy_ugettext('Proxy subversion HTTP requests'),
804 help='' # Do not translate the empty string!
797 help='' # Do not translate the empty string!
805 ),
798 ),
806 LabSetting(
799 LabSetting(
807 key='rhodecode_subversion_http_server_url',
800 key='rhodecode_subversion_http_server_url',
808 type='str',
801 type='str',
809 group=lazy_ugettext('Subversion HTTP Server URL'),
802 group=lazy_ugettext('Subversion HTTP Server URL'),
810 label='', # Do not translate the empty string!
803 label='', # Do not translate the empty string!
811 help=lazy_ugettext('e.g. http://localhost:8080/')
804 help=lazy_ugettext('e.g. http://localhost:8080/')
812 ),
805 ),
813 ]
806 ]
@@ -1,562 +1,561 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 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 this is forms validation classes
22 this is forms validation classes
23 http://formencode.org/module-formencode.validators.html
23 http://formencode.org/module-formencode.validators.html
24 for list off all availible validators
24 for list off all availible validators
25
25
26 we can create our own validators
26 we can create our own validators
27
27
28 The table below outlines the options which can be used in a schema in addition to the validators themselves
28 The table below outlines the options which can be used in a schema in addition to the validators themselves
29 pre_validators [] These validators will be applied before the schema
29 pre_validators [] These validators will be applied before the schema
30 chained_validators [] These validators will be applied after the schema
30 chained_validators [] These validators will be applied after the schema
31 allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
31 allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
32 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
32 filter_extra_fields False If True, then keys that aren't associated with a validator are removed
33 if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
33 if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
34 ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already
34 ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already
35
35
36
36
37 <name> = formencode.validators.<name of validator>
37 <name> = formencode.validators.<name of validator>
38 <name> must equal form name
38 <name> must equal form name
39 list=[1,2,3,4,5]
39 list=[1,2,3,4,5]
40 for SELECT use formencode.All(OneOf(list), Int())
40 for SELECT use formencode.All(OneOf(list), Int())
41
41
42 """
42 """
43
43
44 import logging
44 import logging
45
45
46 import formencode
46 import formencode
47 from formencode import All, Pipe
47 from formencode import All, Pipe
48
48
49 from pylons.i18n.translation import _
49 from pylons.i18n.translation import _
50
50
51 from rhodecode import BACKENDS
51 from rhodecode import BACKENDS
52 from rhodecode.model import validators as v
52 from rhodecode.model import validators as v
53
53
54 log = logging.getLogger(__name__)
54 log = logging.getLogger(__name__)
55
55
56
56
57 def LoginForm():
57 def LoginForm():
58 class _LoginForm(formencode.Schema):
58 class _LoginForm(formencode.Schema):
59 allow_extra_fields = True
59 allow_extra_fields = True
60 filter_extra_fields = True
60 filter_extra_fields = True
61 username = v.UnicodeString(
61 username = v.UnicodeString(
62 strip=True,
62 strip=True,
63 min=1,
63 min=1,
64 not_empty=True,
64 not_empty=True,
65 messages={
65 messages={
66 'empty': _(u'Please enter a login'),
66 'empty': _(u'Please enter a login'),
67 'tooShort': _(u'Enter a value %(min)i characters long or more')
67 'tooShort': _(u'Enter a value %(min)i characters long or more')
68 }
68 }
69 )
69 )
70
70
71 password = v.UnicodeString(
71 password = v.UnicodeString(
72 strip=False,
72 strip=False,
73 min=3,
73 min=3,
74 not_empty=True,
74 not_empty=True,
75 messages={
75 messages={
76 'empty': _(u'Please enter a password'),
76 'empty': _(u'Please enter a password'),
77 'tooShort': _(u'Enter %(min)i characters or more')}
77 'tooShort': _(u'Enter %(min)i characters or more')}
78 )
78 )
79
79
80 remember = v.StringBoolean(if_missing=False)
80 remember = v.StringBoolean(if_missing=False)
81
81
82 chained_validators = [v.ValidAuth()]
82 chained_validators = [v.ValidAuth()]
83 return _LoginForm
83 return _LoginForm
84
84
85
85
86 def PasswordChangeForm(username):
86 def PasswordChangeForm(username):
87 class _PasswordChangeForm(formencode.Schema):
87 class _PasswordChangeForm(formencode.Schema):
88 allow_extra_fields = True
88 allow_extra_fields = True
89 filter_extra_fields = True
89 filter_extra_fields = True
90
90
91 current_password = v.ValidOldPassword(username)(not_empty=True)
91 current_password = v.ValidOldPassword(username)(not_empty=True)
92 new_password = All(v.ValidPassword(), v.UnicodeString(strip=False, min=6))
92 new_password = All(v.ValidPassword(), v.UnicodeString(strip=False, min=6))
93 new_password_confirmation = All(v.ValidPassword(), v.UnicodeString(strip=False, min=6))
93 new_password_confirmation = All(v.ValidPassword(), v.UnicodeString(strip=False, min=6))
94
94
95 chained_validators = [v.ValidPasswordsMatch('new_password',
95 chained_validators = [v.ValidPasswordsMatch('new_password',
96 'new_password_confirmation')]
96 'new_password_confirmation')]
97 return _PasswordChangeForm
97 return _PasswordChangeForm
98
98
99
99
100 def UserForm(edit=False, available_languages=[], old_data={}):
100 def UserForm(edit=False, available_languages=[], old_data={}):
101 class _UserForm(formencode.Schema):
101 class _UserForm(formencode.Schema):
102 allow_extra_fields = True
102 allow_extra_fields = True
103 filter_extra_fields = True
103 filter_extra_fields = True
104 username = All(v.UnicodeString(strip=True, min=1, not_empty=True),
104 username = All(v.UnicodeString(strip=True, min=1, not_empty=True),
105 v.ValidUsername(edit, old_data))
105 v.ValidUsername(edit, old_data))
106 if edit:
106 if edit:
107 new_password = All(
107 new_password = All(
108 v.ValidPassword(),
108 v.ValidPassword(),
109 v.UnicodeString(strip=False, min=6, not_empty=False)
109 v.UnicodeString(strip=False, min=6, not_empty=False)
110 )
110 )
111 password_confirmation = All(
111 password_confirmation = All(
112 v.ValidPassword(),
112 v.ValidPassword(),
113 v.UnicodeString(strip=False, min=6, not_empty=False),
113 v.UnicodeString(strip=False, min=6, not_empty=False),
114 )
114 )
115 admin = v.StringBoolean(if_missing=False)
115 admin = v.StringBoolean(if_missing=False)
116 else:
116 else:
117 password = All(
117 password = All(
118 v.ValidPassword(),
118 v.ValidPassword(),
119 v.UnicodeString(strip=False, min=6, not_empty=True)
119 v.UnicodeString(strip=False, min=6, not_empty=True)
120 )
120 )
121 password_confirmation = All(
121 password_confirmation = All(
122 v.ValidPassword(),
122 v.ValidPassword(),
123 v.UnicodeString(strip=False, min=6, not_empty=False)
123 v.UnicodeString(strip=False, min=6, not_empty=False)
124 )
124 )
125
125
126 password_change = v.StringBoolean(if_missing=False)
126 password_change = v.StringBoolean(if_missing=False)
127 create_repo_group = v.StringBoolean(if_missing=False)
127 create_repo_group = v.StringBoolean(if_missing=False)
128
128
129 active = v.StringBoolean(if_missing=False)
129 active = v.StringBoolean(if_missing=False)
130 firstname = v.UnicodeString(strip=True, min=1, not_empty=False)
130 firstname = v.UnicodeString(strip=True, min=1, not_empty=False)
131 lastname = v.UnicodeString(strip=True, min=1, not_empty=False)
131 lastname = v.UnicodeString(strip=True, min=1, not_empty=False)
132 email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data))
132 email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data))
133 extern_name = v.UnicodeString(strip=True)
133 extern_name = v.UnicodeString(strip=True)
134 extern_type = v.UnicodeString(strip=True)
134 extern_type = v.UnicodeString(strip=True)
135 language = v.OneOf(available_languages, hideList=False,
135 language = v.OneOf(available_languages, hideList=False,
136 testValueList=True, if_missing=None)
136 testValueList=True, if_missing=None)
137 chained_validators = [v.ValidPasswordsMatch()]
137 chained_validators = [v.ValidPasswordsMatch()]
138 return _UserForm
138 return _UserForm
139
139
140
140
141 def UserGroupForm(edit=False, old_data=None, available_members=None,
141 def UserGroupForm(edit=False, old_data=None, available_members=None,
142 allow_disabled=False):
142 allow_disabled=False):
143 old_data = old_data or {}
143 old_data = old_data or {}
144 available_members = available_members or []
144 available_members = available_members or []
145
145
146 class _UserGroupForm(formencode.Schema):
146 class _UserGroupForm(formencode.Schema):
147 allow_extra_fields = True
147 allow_extra_fields = True
148 filter_extra_fields = True
148 filter_extra_fields = True
149
149
150 users_group_name = All(
150 users_group_name = All(
151 v.UnicodeString(strip=True, min=1, not_empty=True),
151 v.UnicodeString(strip=True, min=1, not_empty=True),
152 v.ValidUserGroup(edit, old_data)
152 v.ValidUserGroup(edit, old_data)
153 )
153 )
154 user_group_description = v.UnicodeString(strip=True, min=1,
154 user_group_description = v.UnicodeString(strip=True, min=1,
155 not_empty=False)
155 not_empty=False)
156
156
157 users_group_active = v.StringBoolean(if_missing=False)
157 users_group_active = v.StringBoolean(if_missing=False)
158
158
159 if edit:
159 if edit:
160 users_group_members = v.OneOf(
160 users_group_members = v.OneOf(
161 available_members, hideList=False, testValueList=True,
161 available_members, hideList=False, testValueList=True,
162 if_missing=None, not_empty=False
162 if_missing=None, not_empty=False
163 )
163 )
164 # this is user group owner
164 # this is user group owner
165 user = All(
165 user = All(
166 v.UnicodeString(not_empty=True),
166 v.UnicodeString(not_empty=True),
167 v.ValidRepoUser(allow_disabled))
167 v.ValidRepoUser(allow_disabled))
168 return _UserGroupForm
168 return _UserGroupForm
169
169
170
170
171 def RepoGroupForm(edit=False, old_data=None, available_groups=None,
171 def RepoGroupForm(edit=False, old_data=None, available_groups=None,
172 can_create_in_root=False, allow_disabled=False):
172 can_create_in_root=False, allow_disabled=False):
173 old_data = old_data or {}
173 old_data = old_data or {}
174 available_groups = available_groups or []
174 available_groups = available_groups or []
175
175
176 class _RepoGroupForm(formencode.Schema):
176 class _RepoGroupForm(formencode.Schema):
177 allow_extra_fields = True
177 allow_extra_fields = True
178 filter_extra_fields = False
178 filter_extra_fields = False
179
179
180 group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
180 group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
181 v.SlugifyName(),)
181 v.SlugifyName(),)
182 group_description = v.UnicodeString(strip=True, min=1,
182 group_description = v.UnicodeString(strip=True, min=1,
183 not_empty=False)
183 not_empty=False)
184 group_copy_permissions = v.StringBoolean(if_missing=False)
184 group_copy_permissions = v.StringBoolean(if_missing=False)
185
185
186 group_parent_id = v.OneOf(available_groups, hideList=False,
186 group_parent_id = v.OneOf(available_groups, hideList=False,
187 testValueList=True, not_empty=True)
187 testValueList=True, not_empty=True)
188 enable_locking = v.StringBoolean(if_missing=False)
188 enable_locking = v.StringBoolean(if_missing=False)
189 chained_validators = [
189 chained_validators = [
190 v.ValidRepoGroup(edit, old_data, can_create_in_root)]
190 v.ValidRepoGroup(edit, old_data, can_create_in_root)]
191
191
192 if edit:
192 if edit:
193 # this is repo group owner
193 # this is repo group owner
194 user = All(
194 user = All(
195 v.UnicodeString(not_empty=True),
195 v.UnicodeString(not_empty=True),
196 v.ValidRepoUser(allow_disabled))
196 v.ValidRepoUser(allow_disabled))
197
197
198 return _RepoGroupForm
198 return _RepoGroupForm
199
199
200
200
201 def RegisterForm(edit=False, old_data={}):
201 def RegisterForm(edit=False, old_data={}):
202 class _RegisterForm(formencode.Schema):
202 class _RegisterForm(formencode.Schema):
203 allow_extra_fields = True
203 allow_extra_fields = True
204 filter_extra_fields = True
204 filter_extra_fields = True
205 username = All(
205 username = All(
206 v.ValidUsername(edit, old_data),
206 v.ValidUsername(edit, old_data),
207 v.UnicodeString(strip=True, min=1, not_empty=True)
207 v.UnicodeString(strip=True, min=1, not_empty=True)
208 )
208 )
209 password = All(
209 password = All(
210 v.ValidPassword(),
210 v.ValidPassword(),
211 v.UnicodeString(strip=False, min=6, not_empty=True)
211 v.UnicodeString(strip=False, min=6, not_empty=True)
212 )
212 )
213 password_confirmation = All(
213 password_confirmation = All(
214 v.ValidPassword(),
214 v.ValidPassword(),
215 v.UnicodeString(strip=False, min=6, not_empty=True)
215 v.UnicodeString(strip=False, min=6, not_empty=True)
216 )
216 )
217 active = v.StringBoolean(if_missing=False)
217 active = v.StringBoolean(if_missing=False)
218 firstname = v.UnicodeString(strip=True, min=1, not_empty=False)
218 firstname = v.UnicodeString(strip=True, min=1, not_empty=False)
219 lastname = v.UnicodeString(strip=True, min=1, not_empty=False)
219 lastname = v.UnicodeString(strip=True, min=1, not_empty=False)
220 email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data))
220 email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data))
221
221
222 chained_validators = [v.ValidPasswordsMatch()]
222 chained_validators = [v.ValidPasswordsMatch()]
223
223
224 return _RegisterForm
224 return _RegisterForm
225
225
226
226
227 def PasswordResetForm():
227 def PasswordResetForm():
228 class _PasswordResetForm(formencode.Schema):
228 class _PasswordResetForm(formencode.Schema):
229 allow_extra_fields = True
229 allow_extra_fields = True
230 filter_extra_fields = True
230 filter_extra_fields = True
231 email = All(v.ValidSystemEmail(), v.Email(not_empty=True))
231 email = All(v.ValidSystemEmail(), v.Email(not_empty=True))
232 return _PasswordResetForm
232 return _PasswordResetForm
233
233
234
234
235 def RepoForm(edit=False, old_data=None, repo_groups=None, landing_revs=None,
235 def RepoForm(edit=False, old_data=None, repo_groups=None, landing_revs=None,
236 allow_disabled=False):
236 allow_disabled=False):
237 old_data = old_data or {}
237 old_data = old_data or {}
238 repo_groups = repo_groups or []
238 repo_groups = repo_groups or []
239 landing_revs = landing_revs or []
239 landing_revs = landing_revs or []
240 supported_backends = BACKENDS.keys()
240 supported_backends = BACKENDS.keys()
241
241
242 class _RepoForm(formencode.Schema):
242 class _RepoForm(formencode.Schema):
243 allow_extra_fields = True
243 allow_extra_fields = True
244 filter_extra_fields = False
244 filter_extra_fields = False
245 repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
245 repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
246 v.SlugifyName())
246 v.SlugifyName())
247 repo_group = All(v.CanWriteGroup(old_data),
247 repo_group = All(v.CanWriteGroup(old_data),
248 v.OneOf(repo_groups, hideList=True))
248 v.OneOf(repo_groups, hideList=True))
249 repo_type = v.OneOf(supported_backends, required=False,
249 repo_type = v.OneOf(supported_backends, required=False,
250 if_missing=old_data.get('repo_type'))
250 if_missing=old_data.get('repo_type'))
251 repo_description = v.UnicodeString(strip=True, min=1, not_empty=False)
251 repo_description = v.UnicodeString(strip=True, min=1, not_empty=False)
252 repo_private = v.StringBoolean(if_missing=False)
252 repo_private = v.StringBoolean(if_missing=False)
253 repo_landing_rev = v.OneOf(landing_revs, hideList=True)
253 repo_landing_rev = v.OneOf(landing_revs, hideList=True)
254 repo_copy_permissions = v.StringBoolean(if_missing=False)
254 repo_copy_permissions = v.StringBoolean(if_missing=False)
255 clone_uri = All(v.UnicodeString(strip=True, min=1, not_empty=False))
255 clone_uri = All(v.UnicodeString(strip=True, min=1, not_empty=False))
256
256
257 repo_enable_statistics = v.StringBoolean(if_missing=False)
257 repo_enable_statistics = v.StringBoolean(if_missing=False)
258 repo_enable_downloads = v.StringBoolean(if_missing=False)
258 repo_enable_downloads = v.StringBoolean(if_missing=False)
259 repo_enable_locking = v.StringBoolean(if_missing=False)
259 repo_enable_locking = v.StringBoolean(if_missing=False)
260
260
261 if edit:
261 if edit:
262 # this is repo owner
262 # this is repo owner
263 user = All(
263 user = All(
264 v.UnicodeString(not_empty=True),
264 v.UnicodeString(not_empty=True),
265 v.ValidRepoUser(allow_disabled))
265 v.ValidRepoUser(allow_disabled))
266 clone_uri_change = v.UnicodeString(
266 clone_uri_change = v.UnicodeString(
267 not_empty=False, if_missing=v.Missing)
267 not_empty=False, if_missing=v.Missing)
268
268
269 chained_validators = [v.ValidCloneUri(),
269 chained_validators = [v.ValidCloneUri(),
270 v.ValidRepoName(edit, old_data)]
270 v.ValidRepoName(edit, old_data)]
271 return _RepoForm
271 return _RepoForm
272
272
273
273
274 def RepoPermsForm():
274 def RepoPermsForm():
275 class _RepoPermsForm(formencode.Schema):
275 class _RepoPermsForm(formencode.Schema):
276 allow_extra_fields = True
276 allow_extra_fields = True
277 filter_extra_fields = False
277 filter_extra_fields = False
278 chained_validators = [v.ValidPerms(type_='repo')]
278 chained_validators = [v.ValidPerms(type_='repo')]
279 return _RepoPermsForm
279 return _RepoPermsForm
280
280
281
281
282 def RepoGroupPermsForm(valid_recursive_choices):
282 def RepoGroupPermsForm(valid_recursive_choices):
283 class _RepoGroupPermsForm(formencode.Schema):
283 class _RepoGroupPermsForm(formencode.Schema):
284 allow_extra_fields = True
284 allow_extra_fields = True
285 filter_extra_fields = False
285 filter_extra_fields = False
286 recursive = v.OneOf(valid_recursive_choices)
286 recursive = v.OneOf(valid_recursive_choices)
287 chained_validators = [v.ValidPerms(type_='repo_group')]
287 chained_validators = [v.ValidPerms(type_='repo_group')]
288 return _RepoGroupPermsForm
288 return _RepoGroupPermsForm
289
289
290
290
291 def UserGroupPermsForm():
291 def UserGroupPermsForm():
292 class _UserPermsForm(formencode.Schema):
292 class _UserPermsForm(formencode.Schema):
293 allow_extra_fields = True
293 allow_extra_fields = True
294 filter_extra_fields = False
294 filter_extra_fields = False
295 chained_validators = [v.ValidPerms(type_='user_group')]
295 chained_validators = [v.ValidPerms(type_='user_group')]
296 return _UserPermsForm
296 return _UserPermsForm
297
297
298
298
299 def RepoFieldForm():
299 def RepoFieldForm():
300 class _RepoFieldForm(formencode.Schema):
300 class _RepoFieldForm(formencode.Schema):
301 filter_extra_fields = True
301 filter_extra_fields = True
302 allow_extra_fields = True
302 allow_extra_fields = True
303
303
304 new_field_key = All(v.FieldKey(),
304 new_field_key = All(v.FieldKey(),
305 v.UnicodeString(strip=True, min=3, not_empty=True))
305 v.UnicodeString(strip=True, min=3, not_empty=True))
306 new_field_value = v.UnicodeString(not_empty=False, if_missing=u'')
306 new_field_value = v.UnicodeString(not_empty=False, if_missing=u'')
307 new_field_type = v.OneOf(['str', 'unicode', 'list', 'tuple'],
307 new_field_type = v.OneOf(['str', 'unicode', 'list', 'tuple'],
308 if_missing='str')
308 if_missing='str')
309 new_field_label = v.UnicodeString(not_empty=False)
309 new_field_label = v.UnicodeString(not_empty=False)
310 new_field_desc = v.UnicodeString(not_empty=False)
310 new_field_desc = v.UnicodeString(not_empty=False)
311
311
312 return _RepoFieldForm
312 return _RepoFieldForm
313
313
314
314
315 def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
315 def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
316 repo_groups=[], landing_revs=[]):
316 repo_groups=[], landing_revs=[]):
317 class _RepoForkForm(formencode.Schema):
317 class _RepoForkForm(formencode.Schema):
318 allow_extra_fields = True
318 allow_extra_fields = True
319 filter_extra_fields = False
319 filter_extra_fields = False
320 repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
320 repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
321 v.SlugifyName())
321 v.SlugifyName())
322 repo_group = All(v.CanWriteGroup(),
322 repo_group = All(v.CanWriteGroup(),
323 v.OneOf(repo_groups, hideList=True))
323 v.OneOf(repo_groups, hideList=True))
324 repo_type = All(v.ValidForkType(old_data), v.OneOf(supported_backends))
324 repo_type = All(v.ValidForkType(old_data), v.OneOf(supported_backends))
325 description = v.UnicodeString(strip=True, min=1, not_empty=True)
325 description = v.UnicodeString(strip=True, min=1, not_empty=True)
326 private = v.StringBoolean(if_missing=False)
326 private = v.StringBoolean(if_missing=False)
327 copy_permissions = v.StringBoolean(if_missing=False)
327 copy_permissions = v.StringBoolean(if_missing=False)
328 fork_parent_id = v.UnicodeString()
328 fork_parent_id = v.UnicodeString()
329 chained_validators = [v.ValidForkName(edit, old_data)]
329 chained_validators = [v.ValidForkName(edit, old_data)]
330 landing_rev = v.OneOf(landing_revs, hideList=True)
330 landing_rev = v.OneOf(landing_revs, hideList=True)
331
331
332 return _RepoForkForm
332 return _RepoForkForm
333
333
334
334
335 def ApplicationSettingsForm():
335 def ApplicationSettingsForm():
336 class _ApplicationSettingsForm(formencode.Schema):
336 class _ApplicationSettingsForm(formencode.Schema):
337 allow_extra_fields = True
337 allow_extra_fields = True
338 filter_extra_fields = False
338 filter_extra_fields = False
339 rhodecode_title = v.UnicodeString(strip=True, max=40, not_empty=False)
339 rhodecode_title = v.UnicodeString(strip=True, max=40, not_empty=False)
340 rhodecode_realm = v.UnicodeString(strip=True, min=1, not_empty=True)
340 rhodecode_realm = v.UnicodeString(strip=True, min=1, not_empty=True)
341 rhodecode_pre_code = v.UnicodeString(strip=True, min=1, not_empty=False)
341 rhodecode_pre_code = v.UnicodeString(strip=True, min=1, not_empty=False)
342 rhodecode_post_code = v.UnicodeString(strip=True, min=1, not_empty=False)
342 rhodecode_post_code = v.UnicodeString(strip=True, min=1, not_empty=False)
343 rhodecode_captcha_public_key = v.UnicodeString(strip=True, min=1, not_empty=False)
343 rhodecode_captcha_public_key = v.UnicodeString(strip=True, min=1, not_empty=False)
344 rhodecode_captcha_private_key = v.UnicodeString(strip=True, min=1, not_empty=False)
344 rhodecode_captcha_private_key = v.UnicodeString(strip=True, min=1, not_empty=False)
345
345
346 return _ApplicationSettingsForm
346 return _ApplicationSettingsForm
347
347
348
348
349 def ApplicationVisualisationForm():
349 def ApplicationVisualisationForm():
350 class _ApplicationVisualisationForm(formencode.Schema):
350 class _ApplicationVisualisationForm(formencode.Schema):
351 allow_extra_fields = True
351 allow_extra_fields = True
352 filter_extra_fields = False
352 filter_extra_fields = False
353 rhodecode_show_public_icon = v.StringBoolean(if_missing=False)
353 rhodecode_show_public_icon = v.StringBoolean(if_missing=False)
354 rhodecode_show_private_icon = v.StringBoolean(if_missing=False)
354 rhodecode_show_private_icon = v.StringBoolean(if_missing=False)
355 rhodecode_stylify_metatags = v.StringBoolean(if_missing=False)
355 rhodecode_stylify_metatags = v.StringBoolean(if_missing=False)
356
356
357 rhodecode_repository_fields = v.StringBoolean(if_missing=False)
357 rhodecode_repository_fields = v.StringBoolean(if_missing=False)
358 rhodecode_lightweight_journal = v.StringBoolean(if_missing=False)
358 rhodecode_lightweight_journal = v.StringBoolean(if_missing=False)
359 rhodecode_dashboard_items = v.Int(min=5, not_empty=True)
359 rhodecode_dashboard_items = v.Int(min=5, not_empty=True)
360 rhodecode_admin_grid_items = v.Int(min=5, not_empty=True)
360 rhodecode_admin_grid_items = v.Int(min=5, not_empty=True)
361 rhodecode_show_version = v.StringBoolean(if_missing=False)
361 rhodecode_show_version = v.StringBoolean(if_missing=False)
362 rhodecode_use_gravatar = v.StringBoolean(if_missing=False)
362 rhodecode_use_gravatar = v.StringBoolean(if_missing=False)
363 rhodecode_markup_renderer = v.OneOf(['markdown', 'rst'])
363 rhodecode_markup_renderer = v.OneOf(['markdown', 'rst'])
364 rhodecode_gravatar_url = v.UnicodeString(min=3)
364 rhodecode_gravatar_url = v.UnicodeString(min=3)
365 rhodecode_clone_uri_tmpl = v.UnicodeString(min=3)
365 rhodecode_clone_uri_tmpl = v.UnicodeString(min=3)
366 rhodecode_support_url = v.UnicodeString()
366 rhodecode_support_url = v.UnicodeString()
367 rhodecode_show_revision_number = v.StringBoolean(if_missing=False)
367 rhodecode_show_revision_number = v.StringBoolean(if_missing=False)
368 rhodecode_show_sha_length = v.Int(min=4, not_empty=True)
368 rhodecode_show_sha_length = v.Int(min=4, not_empty=True)
369
369
370 return _ApplicationVisualisationForm
370 return _ApplicationVisualisationForm
371
371
372
372
373 class _BaseVcsSettingsForm(formencode.Schema):
373 class _BaseVcsSettingsForm(formencode.Schema):
374 allow_extra_fields = True
374 allow_extra_fields = True
375 filter_extra_fields = False
375 filter_extra_fields = False
376 hooks_changegroup_repo_size = v.StringBoolean(if_missing=False)
376 hooks_changegroup_repo_size = v.StringBoolean(if_missing=False)
377 hooks_changegroup_push_logger = v.StringBoolean(if_missing=False)
377 hooks_changegroup_push_logger = v.StringBoolean(if_missing=False)
378 hooks_outgoing_pull_logger = v.StringBoolean(if_missing=False)
378 hooks_outgoing_pull_logger = v.StringBoolean(if_missing=False)
379
379
380 extensions_largefiles = v.StringBoolean(if_missing=False)
380 extensions_largefiles = v.StringBoolean(if_missing=False)
381 phases_publish = v.StringBoolean(if_missing=False)
381 phases_publish = v.StringBoolean(if_missing=False)
382
382
383 rhodecode_pr_merge_enabled = v.StringBoolean(if_missing=False)
383 rhodecode_pr_merge_enabled = v.StringBoolean(if_missing=False)
384 rhodecode_use_outdated_comments = v.StringBoolean(if_missing=False)
384 rhodecode_use_outdated_comments = v.StringBoolean(if_missing=False)
385 rhodecode_hg_use_rebase_for_merging = v.StringBoolean(if_missing=False)
385 rhodecode_hg_use_rebase_for_merging = v.StringBoolean(if_missing=False)
386
386
387
387
388 def ApplicationUiSettingsForm():
388 def ApplicationUiSettingsForm():
389 class _ApplicationUiSettingsForm(_BaseVcsSettingsForm):
389 class _ApplicationUiSettingsForm(_BaseVcsSettingsForm):
390 web_push_ssl = v.StringBoolean(if_missing=False)
390 web_push_ssl = v.StringBoolean(if_missing=False)
391 paths_root_path = All(
391 paths_root_path = All(
392 v.ValidPath(),
392 v.ValidPath(),
393 v.UnicodeString(strip=True, min=1, not_empty=True)
393 v.UnicodeString(strip=True, min=1, not_empty=True)
394 )
394 )
395 extensions_hgsubversion = v.StringBoolean(if_missing=False)
395 extensions_hgsubversion = v.StringBoolean(if_missing=False)
396 extensions_hggit = v.StringBoolean(if_missing=False)
396 extensions_hggit = v.StringBoolean(if_missing=False)
397 new_svn_branch = v.ValidSvnPattern(section='vcs_svn_branch')
397 new_svn_branch = v.ValidSvnPattern(section='vcs_svn_branch')
398 new_svn_tag = v.ValidSvnPattern(section='vcs_svn_tag')
398 new_svn_tag = v.ValidSvnPattern(section='vcs_svn_tag')
399
399
400 return _ApplicationUiSettingsForm
400 return _ApplicationUiSettingsForm
401
401
402
402
403 def RepoVcsSettingsForm(repo_name):
403 def RepoVcsSettingsForm(repo_name):
404 class _RepoVcsSettingsForm(_BaseVcsSettingsForm):
404 class _RepoVcsSettingsForm(_BaseVcsSettingsForm):
405 inherit_global_settings = v.StringBoolean(if_missing=False)
405 inherit_global_settings = v.StringBoolean(if_missing=False)
406 new_svn_branch = v.ValidSvnPattern(
406 new_svn_branch = v.ValidSvnPattern(
407 section='vcs_svn_branch', repo_name=repo_name)
407 section='vcs_svn_branch', repo_name=repo_name)
408 new_svn_tag = v.ValidSvnPattern(
408 new_svn_tag = v.ValidSvnPattern(
409 section='vcs_svn_tag', repo_name=repo_name)
409 section='vcs_svn_tag', repo_name=repo_name)
410
410
411 return _RepoVcsSettingsForm
411 return _RepoVcsSettingsForm
412
412
413
413
414 def LabsSettingsForm():
414 def LabsSettingsForm():
415 class _LabSettingsForm(formencode.Schema):
415 class _LabSettingsForm(formencode.Schema):
416 allow_extra_fields = True
416 allow_extra_fields = True
417 filter_extra_fields = False
417 filter_extra_fields = False
418
418
419 rhodecode_hg_use_rebase_for_merging = v.StringBoolean(if_missing=False)
420 rhodecode_proxy_subversion_http_requests = v.StringBoolean(
419 rhodecode_proxy_subversion_http_requests = v.StringBoolean(
421 if_missing=False)
420 if_missing=False)
422 rhodecode_subversion_http_server_url = v.UnicodeString(
421 rhodecode_subversion_http_server_url = v.UnicodeString(
423 strip=True, if_missing=None)
422 strip=True, if_missing=None)
424
423
425 return _LabSettingsForm
424 return _LabSettingsForm
426
425
427
426
428 def ApplicationPermissionsForm(register_choices, extern_activate_choices):
427 def ApplicationPermissionsForm(register_choices, extern_activate_choices):
429 class _DefaultPermissionsForm(formencode.Schema):
428 class _DefaultPermissionsForm(formencode.Schema):
430 allow_extra_fields = True
429 allow_extra_fields = True
431 filter_extra_fields = True
430 filter_extra_fields = True
432
431
433 anonymous = v.StringBoolean(if_missing=False)
432 anonymous = v.StringBoolean(if_missing=False)
434 default_register = v.OneOf(register_choices)
433 default_register = v.OneOf(register_choices)
435 default_register_message = v.UnicodeString()
434 default_register_message = v.UnicodeString()
436 default_extern_activate = v.OneOf(extern_activate_choices)
435 default_extern_activate = v.OneOf(extern_activate_choices)
437
436
438 return _DefaultPermissionsForm
437 return _DefaultPermissionsForm
439
438
440
439
441 def ObjectPermissionsForm(repo_perms_choices, group_perms_choices,
440 def ObjectPermissionsForm(repo_perms_choices, group_perms_choices,
442 user_group_perms_choices):
441 user_group_perms_choices):
443 class _ObjectPermissionsForm(formencode.Schema):
442 class _ObjectPermissionsForm(formencode.Schema):
444 allow_extra_fields = True
443 allow_extra_fields = True
445 filter_extra_fields = True
444 filter_extra_fields = True
446 overwrite_default_repo = v.StringBoolean(if_missing=False)
445 overwrite_default_repo = v.StringBoolean(if_missing=False)
447 overwrite_default_group = v.StringBoolean(if_missing=False)
446 overwrite_default_group = v.StringBoolean(if_missing=False)
448 overwrite_default_user_group = v.StringBoolean(if_missing=False)
447 overwrite_default_user_group = v.StringBoolean(if_missing=False)
449 default_repo_perm = v.OneOf(repo_perms_choices)
448 default_repo_perm = v.OneOf(repo_perms_choices)
450 default_group_perm = v.OneOf(group_perms_choices)
449 default_group_perm = v.OneOf(group_perms_choices)
451 default_user_group_perm = v.OneOf(user_group_perms_choices)
450 default_user_group_perm = v.OneOf(user_group_perms_choices)
452
451
453 return _ObjectPermissionsForm
452 return _ObjectPermissionsForm
454
453
455
454
456 def UserPermissionsForm(create_choices, create_on_write_choices,
455 def UserPermissionsForm(create_choices, create_on_write_choices,
457 repo_group_create_choices, user_group_create_choices,
456 repo_group_create_choices, user_group_create_choices,
458 fork_choices, inherit_default_permissions_choices):
457 fork_choices, inherit_default_permissions_choices):
459 class _DefaultPermissionsForm(formencode.Schema):
458 class _DefaultPermissionsForm(formencode.Schema):
460 allow_extra_fields = True
459 allow_extra_fields = True
461 filter_extra_fields = True
460 filter_extra_fields = True
462
461
463 anonymous = v.StringBoolean(if_missing=False)
462 anonymous = v.StringBoolean(if_missing=False)
464
463
465 default_repo_create = v.OneOf(create_choices)
464 default_repo_create = v.OneOf(create_choices)
466 default_repo_create_on_write = v.OneOf(create_on_write_choices)
465 default_repo_create_on_write = v.OneOf(create_on_write_choices)
467 default_user_group_create = v.OneOf(user_group_create_choices)
466 default_user_group_create = v.OneOf(user_group_create_choices)
468 default_repo_group_create = v.OneOf(repo_group_create_choices)
467 default_repo_group_create = v.OneOf(repo_group_create_choices)
469 default_fork_create = v.OneOf(fork_choices)
468 default_fork_create = v.OneOf(fork_choices)
470 default_inherit_default_permissions = v.OneOf(inherit_default_permissions_choices)
469 default_inherit_default_permissions = v.OneOf(inherit_default_permissions_choices)
471
470
472 return _DefaultPermissionsForm
471 return _DefaultPermissionsForm
473
472
474
473
475 def UserIndividualPermissionsForm():
474 def UserIndividualPermissionsForm():
476 class _DefaultPermissionsForm(formencode.Schema):
475 class _DefaultPermissionsForm(formencode.Schema):
477 allow_extra_fields = True
476 allow_extra_fields = True
478 filter_extra_fields = True
477 filter_extra_fields = True
479
478
480 inherit_default_permissions = v.StringBoolean(if_missing=False)
479 inherit_default_permissions = v.StringBoolean(if_missing=False)
481
480
482 return _DefaultPermissionsForm
481 return _DefaultPermissionsForm
483
482
484
483
485 def DefaultsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys()):
484 def DefaultsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys()):
486 class _DefaultsForm(formencode.Schema):
485 class _DefaultsForm(formencode.Schema):
487 allow_extra_fields = True
486 allow_extra_fields = True
488 filter_extra_fields = True
487 filter_extra_fields = True
489 default_repo_type = v.OneOf(supported_backends)
488 default_repo_type = v.OneOf(supported_backends)
490 default_repo_private = v.StringBoolean(if_missing=False)
489 default_repo_private = v.StringBoolean(if_missing=False)
491 default_repo_enable_statistics = v.StringBoolean(if_missing=False)
490 default_repo_enable_statistics = v.StringBoolean(if_missing=False)
492 default_repo_enable_downloads = v.StringBoolean(if_missing=False)
491 default_repo_enable_downloads = v.StringBoolean(if_missing=False)
493 default_repo_enable_locking = v.StringBoolean(if_missing=False)
492 default_repo_enable_locking = v.StringBoolean(if_missing=False)
494
493
495 return _DefaultsForm
494 return _DefaultsForm
496
495
497
496
498 def AuthSettingsForm():
497 def AuthSettingsForm():
499 class _AuthSettingsForm(formencode.Schema):
498 class _AuthSettingsForm(formencode.Schema):
500 allow_extra_fields = True
499 allow_extra_fields = True
501 filter_extra_fields = True
500 filter_extra_fields = True
502 auth_plugins = All(v.ValidAuthPlugins(),
501 auth_plugins = All(v.ValidAuthPlugins(),
503 v.UniqueListFromString()(not_empty=True))
502 v.UniqueListFromString()(not_empty=True))
504
503
505 return _AuthSettingsForm
504 return _AuthSettingsForm
506
505
507
506
508 def UserExtraEmailForm():
507 def UserExtraEmailForm():
509 class _UserExtraEmailForm(formencode.Schema):
508 class _UserExtraEmailForm(formencode.Schema):
510 email = All(v.UniqSystemEmail(), v.Email(not_empty=True))
509 email = All(v.UniqSystemEmail(), v.Email(not_empty=True))
511 return _UserExtraEmailForm
510 return _UserExtraEmailForm
512
511
513
512
514 def UserExtraIpForm():
513 def UserExtraIpForm():
515 class _UserExtraIpForm(formencode.Schema):
514 class _UserExtraIpForm(formencode.Schema):
516 ip = v.ValidIp()(not_empty=True)
515 ip = v.ValidIp()(not_empty=True)
517 return _UserExtraIpForm
516 return _UserExtraIpForm
518
517
519
518
520 def PullRequestForm(repo_id):
519 def PullRequestForm(repo_id):
521 class _PullRequestForm(formencode.Schema):
520 class _PullRequestForm(formencode.Schema):
522 allow_extra_fields = True
521 allow_extra_fields = True
523 filter_extra_fields = True
522 filter_extra_fields = True
524
523
525 user = v.UnicodeString(strip=True, required=True)
524 user = v.UnicodeString(strip=True, required=True)
526 source_repo = v.UnicodeString(strip=True, required=True)
525 source_repo = v.UnicodeString(strip=True, required=True)
527 source_ref = v.UnicodeString(strip=True, required=True)
526 source_ref = v.UnicodeString(strip=True, required=True)
528 target_repo = v.UnicodeString(strip=True, required=True)
527 target_repo = v.UnicodeString(strip=True, required=True)
529 target_ref = v.UnicodeString(strip=True, required=True)
528 target_ref = v.UnicodeString(strip=True, required=True)
530 revisions = All(#v.NotReviewedRevisions(repo_id)(),
529 revisions = All(#v.NotReviewedRevisions(repo_id)(),
531 v.UniqueList()(not_empty=True))
530 v.UniqueList()(not_empty=True))
532 review_members = v.UniqueList(convert=int)(not_empty=True)
531 review_members = v.UniqueList(convert=int)(not_empty=True)
533
532
534 pullrequest_title = v.UnicodeString(strip=True, required=True)
533 pullrequest_title = v.UnicodeString(strip=True, required=True)
535 pullrequest_desc = v.UnicodeString(strip=True, required=False)
534 pullrequest_desc = v.UnicodeString(strip=True, required=False)
536
535
537 return _PullRequestForm
536 return _PullRequestForm
538
537
539
538
540 def GistForm(lifetime_options, acl_level_options):
539 def GistForm(lifetime_options, acl_level_options):
541 class _GistForm(formencode.Schema):
540 class _GistForm(formencode.Schema):
542
541
543 gistid = All(v.UniqGistId(), v.UnicodeString(strip=True, min=3, not_empty=False, if_missing=None))
542 gistid = All(v.UniqGistId(), v.UnicodeString(strip=True, min=3, not_empty=False, if_missing=None))
544 filename = All(v.BasePath()(),
543 filename = All(v.BasePath()(),
545 v.UnicodeString(strip=True, required=False))
544 v.UnicodeString(strip=True, required=False))
546 description = v.UnicodeString(required=False, if_missing=u'')
545 description = v.UnicodeString(required=False, if_missing=u'')
547 lifetime = v.OneOf(lifetime_options)
546 lifetime = v.OneOf(lifetime_options)
548 mimetype = v.UnicodeString(required=False, if_missing=None)
547 mimetype = v.UnicodeString(required=False, if_missing=None)
549 content = v.UnicodeString(required=True, not_empty=True)
548 content = v.UnicodeString(required=True, not_empty=True)
550 public = v.UnicodeString(required=False, if_missing=u'')
549 public = v.UnicodeString(required=False, if_missing=u'')
551 private = v.UnicodeString(required=False, if_missing=u'')
550 private = v.UnicodeString(required=False, if_missing=u'')
552 acl_level = v.OneOf(acl_level_options)
551 acl_level = v.OneOf(acl_level_options)
553
552
554 return _GistForm
553 return _GistForm
555
554
556
555
557 def IssueTrackerPatternsForm():
556 def IssueTrackerPatternsForm():
558 class _IssueTrackerPatternsForm(formencode.Schema):
557 class _IssueTrackerPatternsForm(formencode.Schema):
559 allow_extra_fields = True
558 allow_extra_fields = True
560 filter_extra_fields = False
559 filter_extra_fields = False
561 chained_validators = [v.ValidPattern()]
560 chained_validators = [v.ValidPattern()]
562 return _IssueTrackerPatternsForm
561 return _IssueTrackerPatternsForm
General Comments 0
You need to be logged in to leave comments. Login now