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