##// END OF EJS Templates
login: moved to apps module
marcink -
r1501:a960166a default
parent child Browse files
Show More
1 NO CONTENT: file renamed from rhodecode/login/__init__.py to rhodecode/apps/login/__init__.py
1 NO CONTENT: file renamed from rhodecode/login/tests/__init__.py to rhodecode/apps/login/tests/__init__.py
@@ -1,128 +1,128 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 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 import mock
23 23 import pytest
24 24
25 from rhodecode.apps.login.views import LoginView, CaptchaData
25 26 from rhodecode.config.routing import ADMIN_PREFIX
26 from rhodecode.login.views import LoginView, CaptchaData
27 27 from rhodecode.model.settings import SettingsModel
28 28 from rhodecode.tests.utils import AssertResponse
29 29
30 30
31 31 class RhodeCodeSetting(object):
32 32 def __init__(self, name, value):
33 33 self.name = name
34 34 self.value = value
35 35
36 36 def __enter__(self):
37 37 from rhodecode.model.settings import SettingsModel
38 38 model = SettingsModel()
39 39 self.old_setting = model.get_setting_by_name(self.name)
40 40 model.create_or_update_setting(name=self.name, val=self.value)
41 41 return self
42 42
43 43 def __exit__(self, type, value, traceback):
44 44 model = SettingsModel()
45 45 if self.old_setting:
46 46 model.create_or_update_setting(
47 47 name=self.name, val=self.old_setting.app_settings_value)
48 48 else:
49 49 model.create_or_update_setting(name=self.name)
50 50
51 51
52 52 class TestRegisterCaptcha(object):
53 53
54 54 @pytest.mark.parametrize('private_key, public_key, expected', [
55 55 ('', '', CaptchaData(False, '', '')),
56 56 ('', 'pubkey', CaptchaData(False, '', 'pubkey')),
57 57 ('privkey', '', CaptchaData(True, 'privkey', '')),
58 58 ('privkey', 'pubkey', CaptchaData(True, 'privkey', 'pubkey')),
59 59 ])
60 60 def test_get_captcha_data(self, private_key, public_key, expected, db):
61 61 login_view = LoginView(mock.Mock(), mock.Mock())
62 62 with RhodeCodeSetting('captcha_private_key', private_key):
63 63 with RhodeCodeSetting('captcha_public_key', public_key):
64 64 captcha = login_view._get_captcha_data()
65 65 assert captcha == expected
66 66
67 67 @pytest.mark.parametrize('active', [False, True])
68 68 @mock.patch.object(LoginView, '_get_captcha_data')
69 69 def test_private_key_does_not_leak_to_html(
70 70 self, m_get_captcha_data, active, app):
71 71 captcha = CaptchaData(
72 72 active=active, private_key='PRIVATE_KEY', public_key='PUBLIC_KEY')
73 73 m_get_captcha_data.return_value = captcha
74 74
75 75 response = app.get(ADMIN_PREFIX + '/register')
76 76 assert 'PRIVATE_KEY' not in response
77 77
78 78 @pytest.mark.parametrize('active', [False, True])
79 79 @mock.patch.object(LoginView, '_get_captcha_data')
80 80 def test_register_view_renders_captcha(
81 81 self, m_get_captcha_data, active, app):
82 82 captcha = CaptchaData(
83 83 active=active, private_key='PRIVATE_KEY', public_key='PUBLIC_KEY')
84 84 m_get_captcha_data.return_value = captcha
85 85
86 86 response = app.get(ADMIN_PREFIX + '/register')
87 87
88 88 assertr = AssertResponse(response)
89 89 if active:
90 90 assertr.one_element_exists('#recaptcha_field')
91 91 else:
92 92 assertr.no_element_exists('#recaptcha_field')
93 93
94 94 @pytest.mark.parametrize('valid', [False, True])
95 @mock.patch('rhodecode.login.views.submit')
95 @mock.patch('rhodecode.apps.login.views.submit')
96 96 @mock.patch.object(LoginView, '_get_captcha_data')
97 97 def test_register_with_active_captcha(
98 98 self, m_get_captcha_data, m_submit, valid, app, csrf_token):
99 99 captcha = CaptchaData(
100 100 active=True, private_key='PRIVATE_KEY', public_key='PUBLIC_KEY')
101 101 m_get_captcha_data.return_value = captcha
102 102 m_response = mock.Mock()
103 103 m_response.is_valid = valid
104 104 m_submit.return_value = m_response
105 105
106 106 params = {
107 107 'csrf_token': csrf_token,
108 108 'email': 'pytest@example.com',
109 109 'firstname': 'pytest-firstname',
110 110 'lastname': 'pytest-lastname',
111 111 'password': 'secret',
112 112 'password_confirmation': 'secret',
113 113 'username': 'pytest',
114 114 }
115 115 response = app.post(ADMIN_PREFIX + '/register', params=params)
116 116
117 117 if valid:
118 118 # If we provided a valid captcha input we expect a successful
119 119 # registration and redirect to the login page.
120 120 assert response.status_int == 302
121 121 assert 'location' in response.headers
122 122 assert ADMIN_PREFIX + '/login' in response.headers['location']
123 123 else:
124 124 # If captche input is invalid we expect to stay on the registration
125 125 # page with an error message displayed.
126 126 assertr = AssertResponse(response)
127 127 assert response.status_int == 200
128 128 assertr.one_element_exists('#recaptcha_field ~ span.error-message')
1 NO CONTENT: file renamed from rhodecode/login/views.py to rhodecode/apps/login/views.py
@@ -1,495 +1,495 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 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 Pylons middleware initialization
23 23 """
24 24 import logging
25 25 from collections import OrderedDict
26 26
27 27 from paste.registry import RegistryManager
28 28 from paste.gzipper import make_gzip_middleware
29 29 from pylons.wsgiapp import PylonsApp
30 30 from pyramid.authorization import ACLAuthorizationPolicy
31 31 from pyramid.config import Configurator
32 32 from pyramid.settings import asbool, aslist
33 33 from pyramid.wsgi import wsgiapp
34 34 from pyramid.httpexceptions import (
35 35 HTTPException, HTTPError, HTTPInternalServerError, HTTPFound)
36 36 from pyramid.events import ApplicationCreated
37 37 from pyramid.renderers import render_to_response
38 38 from routes.middleware import RoutesMiddleware
39 39 import routes.util
40 40
41 41 import rhodecode
42 42 from rhodecode.model import meta
43 43 from rhodecode.config import patches
44 44 from rhodecode.config.routing import STATIC_FILE_PREFIX
45 45 from rhodecode.config.environment import (
46 46 load_environment, load_pyramid_environment)
47 47 from rhodecode.lib.middleware import csrf
48 48 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
49 49 from rhodecode.lib.middleware.error_handling import (
50 50 PylonsErrorHandlingMiddleware)
51 51 from rhodecode.lib.middleware.https_fixup import HttpsFixup
52 52 from rhodecode.lib.middleware.vcs import VCSMiddleware
53 53 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
54 54 from rhodecode.lib.utils2 import aslist as rhodecode_aslist
55 55 from rhodecode.subscribers import (
56 56 scan_repositories_if_enabled, write_metadata_if_needed)
57 57
58 58
59 59 log = logging.getLogger(__name__)
60 60
61 61
62 62 # this is used to avoid avoid the route lookup overhead in routesmiddleware
63 63 # for certain routes which won't go to pylons to - eg. static files, debugger
64 64 # it is only needed for the pylons migration and can be removed once complete
65 65 class SkippableRoutesMiddleware(RoutesMiddleware):
66 66 """ Routes middleware that allows you to skip prefixes """
67 67
68 68 def __init__(self, *args, **kw):
69 69 self.skip_prefixes = kw.pop('skip_prefixes', [])
70 70 super(SkippableRoutesMiddleware, self).__init__(*args, **kw)
71 71
72 72 def __call__(self, environ, start_response):
73 73 for prefix in self.skip_prefixes:
74 74 if environ['PATH_INFO'].startswith(prefix):
75 75 # added to avoid the case when a missing /_static route falls
76 76 # through to pylons and causes an exception as pylons is
77 77 # expecting wsgiorg.routingargs to be set in the environ
78 78 # by RoutesMiddleware.
79 79 if 'wsgiorg.routing_args' not in environ:
80 80 environ['wsgiorg.routing_args'] = (None, {})
81 81 return self.app(environ, start_response)
82 82
83 83 return super(SkippableRoutesMiddleware, self).__call__(
84 84 environ, start_response)
85 85
86 86
87 87 def make_app(global_conf, static_files=True, **app_conf):
88 88 """Create a Pylons WSGI application and return it
89 89
90 90 ``global_conf``
91 91 The inherited configuration for this application. Normally from
92 92 the [DEFAULT] section of the Paste ini file.
93 93
94 94 ``app_conf``
95 95 The application's local configuration. Normally specified in
96 96 the [app:<name>] section of the Paste ini file (where <name>
97 97 defaults to main).
98 98
99 99 """
100 100 # Apply compatibility patches
101 101 patches.kombu_1_5_1_python_2_7_11()
102 102 patches.inspect_getargspec()
103 103
104 104 # Configure the Pylons environment
105 105 config = load_environment(global_conf, app_conf)
106 106
107 107 # The Pylons WSGI app
108 108 app = PylonsApp(config=config)
109 109 if rhodecode.is_test:
110 110 app = csrf.CSRFDetector(app)
111 111
112 112 expected_origin = config.get('expected_origin')
113 113 if expected_origin:
114 114 # The API can be accessed from other Origins.
115 115 app = csrf.OriginChecker(app, expected_origin,
116 116 skip_urls=[routes.util.url_for('api')])
117 117
118 118 # Establish the Registry for this application
119 119 app = RegistryManager(app)
120 120
121 121 app.config = config
122 122
123 123 return app
124 124
125 125
126 126 def make_pyramid_app(global_config, **settings):
127 127 """
128 128 Constructs the WSGI application based on Pyramid and wraps the Pylons based
129 129 application.
130 130
131 131 Specials:
132 132
133 133 * We migrate from Pylons to Pyramid. While doing this, we keep both
134 134 frameworks functional. This involves moving some WSGI middlewares around
135 135 and providing access to some data internals, so that the old code is
136 136 still functional.
137 137
138 138 * The application can also be integrated like a plugin via the call to
139 139 `includeme`. This is accompanied with the other utility functions which
140 140 are called. Changing this should be done with great care to not break
141 141 cases when these fragments are assembled from another place.
142 142
143 143 """
144 144 # The edition string should be available in pylons too, so we add it here
145 145 # before copying the settings.
146 146 settings.setdefault('rhodecode.edition', 'Community Edition')
147 147
148 148 # As long as our Pylons application does expect "unprepared" settings, make
149 149 # sure that we keep an unmodified copy. This avoids unintentional change of
150 150 # behavior in the old application.
151 151 settings_pylons = settings.copy()
152 152
153 153 sanitize_settings_and_apply_defaults(settings)
154 154 config = Configurator(settings=settings)
155 155 add_pylons_compat_data(config.registry, global_config, settings_pylons)
156 156
157 157 load_pyramid_environment(global_config, settings)
158 158
159 159 includeme_first(config)
160 160 includeme(config)
161 161 pyramid_app = config.make_wsgi_app()
162 162 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
163 163 pyramid_app.config = config
164 164
165 165 # creating the app uses a connection - return it after we are done
166 166 meta.Session.remove()
167 167
168 168 return pyramid_app
169 169
170 170
171 171 def make_not_found_view(config):
172 172 """
173 173 This creates the view which should be registered as not-found-view to
174 174 pyramid. Basically it contains of the old pylons app, converted to a view.
175 175 Additionally it is wrapped by some other middlewares.
176 176 """
177 177 settings = config.registry.settings
178 178 vcs_server_enabled = settings['vcs.server.enable']
179 179
180 180 # Make pylons app from unprepared settings.
181 181 pylons_app = make_app(
182 182 config.registry._pylons_compat_global_config,
183 183 **config.registry._pylons_compat_settings)
184 184 config.registry._pylons_compat_config = pylons_app.config
185 185
186 186 # Appenlight monitoring.
187 187 pylons_app, appenlight_client = wrap_in_appenlight_if_enabled(
188 188 pylons_app, settings)
189 189
190 190 # The pylons app is executed inside of the pyramid 404 exception handler.
191 191 # Exceptions which are raised inside of it are not handled by pyramid
192 192 # again. Therefore we add a middleware that invokes the error handler in
193 193 # case of an exception or error response. This way we return proper error
194 194 # HTML pages in case of an error.
195 195 reraise = (settings.get('debugtoolbar.enabled', False) or
196 196 rhodecode.disable_error_handler)
197 197 pylons_app = PylonsErrorHandlingMiddleware(
198 198 pylons_app, error_handler, reraise)
199 199
200 200 # The VCSMiddleware shall operate like a fallback if pyramid doesn't find a
201 201 # view to handle the request. Therefore it is wrapped around the pylons
202 202 # app. It has to be outside of the error handling otherwise error responses
203 203 # from the vcsserver are converted to HTML error pages. This confuses the
204 204 # command line tools and the user won't get a meaningful error message.
205 205 if vcs_server_enabled:
206 206 pylons_app = VCSMiddleware(
207 207 pylons_app, settings, appenlight_client, registry=config.registry)
208 208
209 209 # Convert WSGI app to pyramid view and return it.
210 210 return wsgiapp(pylons_app)
211 211
212 212
213 213 def add_pylons_compat_data(registry, global_config, settings):
214 214 """
215 215 Attach data to the registry to support the Pylons integration.
216 216 """
217 217 registry._pylons_compat_global_config = global_config
218 218 registry._pylons_compat_settings = settings
219 219
220 220
221 221 def error_handler(exception, request):
222 222 import rhodecode
223 223 from rhodecode.lib.utils2 import AttributeDict
224 224
225 225 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
226 226
227 227 base_response = HTTPInternalServerError()
228 228 # prefer original exception for the response since it may have headers set
229 229 if isinstance(exception, HTTPException):
230 230 base_response = exception
231 231
232 232 def is_http_error(response):
233 233 # error which should have traceback
234 234 return response.status_code > 499
235 235
236 236 if is_http_error(base_response):
237 237 log.exception(
238 238 'error occurred handling this request for path: %s', request.path)
239 239
240 240 c = AttributeDict()
241 241 c.error_message = base_response.status
242 242 c.error_explanation = base_response.explanation or str(base_response)
243 243 c.visual = AttributeDict()
244 244
245 245 c.visual.rhodecode_support_url = (
246 246 request.registry.settings.get('rhodecode_support_url') or
247 247 request.route_url('rhodecode_support')
248 248 )
249 249 c.redirect_time = 0
250 250 c.rhodecode_name = rhodecode_title
251 251 if not c.rhodecode_name:
252 252 c.rhodecode_name = 'Rhodecode'
253 253
254 254 c.causes = []
255 255 if hasattr(base_response, 'causes'):
256 256 c.causes = base_response.causes
257 257
258 258 response = render_to_response(
259 259 '/errors/error_document.mako', {'c': c}, request=request,
260 260 response=base_response)
261 261
262 262 return response
263 263
264 264
265 265 def includeme(config):
266 266 settings = config.registry.settings
267 267
268 268 # plugin information
269 269 config.registry.rhodecode_plugins = OrderedDict()
270 270
271 271 config.add_directive(
272 272 'register_rhodecode_plugin', register_rhodecode_plugin)
273 273
274 274 if asbool(settings.get('appenlight', 'false')):
275 275 config.include('appenlight_client.ext.pyramid_tween')
276 276
277 277 # Includes which are required. The application would fail without them.
278 278 config.include('pyramid_mako')
279 279 config.include('pyramid_beaker')
280 280 config.include('rhodecode.channelstream')
281 281 config.include('rhodecode.admin')
282 282 config.include('rhodecode.authentication')
283 283 config.include('rhodecode.integrations')
284 config.include('rhodecode.login')
284 config.include('rhodecode.apps.login')
285 285 config.include('rhodecode.tweens')
286 286 config.include('rhodecode.api')
287 287 config.include('rhodecode.svn_support')
288 288 config.add_route(
289 289 'rhodecode_support', 'https://rhodecode.com/help/', static=True)
290 290
291 291 config.add_translation_dirs('rhodecode:i18n/')
292 292 settings['default_locale_name'] = settings.get('lang', 'en')
293 293
294 294 # Add subscribers.
295 295 config.add_subscriber(scan_repositories_if_enabled, ApplicationCreated)
296 296 config.add_subscriber(write_metadata_if_needed, ApplicationCreated)
297 297
298 298 # Set the authorization policy.
299 299 authz_policy = ACLAuthorizationPolicy()
300 300 config.set_authorization_policy(authz_policy)
301 301
302 302 # Set the default renderer for HTML templates to mako.
303 303 config.add_mako_renderer('.html')
304 304
305 305 # include RhodeCode plugins
306 306 includes = aslist(settings.get('rhodecode.includes', []))
307 307 for inc in includes:
308 308 config.include(inc)
309 309
310 310 # This is the glue which allows us to migrate in chunks. By registering the
311 311 # pylons based application as the "Not Found" view in Pyramid, we will
312 312 # fallback to the old application each time the new one does not yet know
313 313 # how to handle a request.
314 314 config.add_notfound_view(make_not_found_view(config))
315 315
316 316 if not settings.get('debugtoolbar.enabled', False):
317 317 # if no toolbar, then any exception gets caught and rendered
318 318 config.add_view(error_handler, context=Exception)
319 319
320 320 config.add_view(error_handler, context=HTTPError)
321 321
322 322
323 323 def includeme_first(config):
324 324 # redirect automatic browser favicon.ico requests to correct place
325 325 def favicon_redirect(context, request):
326 326 return HTTPFound(
327 327 request.static_path('rhodecode:public/images/favicon.ico'))
328 328
329 329 config.add_view(favicon_redirect, route_name='favicon')
330 330 config.add_route('favicon', '/favicon.ico')
331 331
332 332 def robots_redirect(context, request):
333 333 return HTTPFound(
334 334 request.static_path('rhodecode:public/robots.txt'))
335 335
336 336 config.add_view(robots_redirect, route_name='robots')
337 337 config.add_route('robots', '/robots.txt')
338 338
339 339 config.add_static_view(
340 340 '_static/deform', 'deform:static')
341 341 config.add_static_view(
342 342 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
343 343
344 344
345 345 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
346 346 """
347 347 Apply outer WSGI middlewares around the application.
348 348
349 349 Part of this has been moved up from the Pylons layer, so that the
350 350 data is also available if old Pylons code is hit through an already ported
351 351 view.
352 352 """
353 353 settings = config.registry.settings
354 354
355 355 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
356 356 pyramid_app = HttpsFixup(pyramid_app, settings)
357 357
358 358 # Add RoutesMiddleware to support the pylons compatibility tween during
359 359 # migration to pyramid.
360 360 pyramid_app = SkippableRoutesMiddleware(
361 361 pyramid_app, config.registry._pylons_compat_config['routes.map'],
362 362 skip_prefixes=(STATIC_FILE_PREFIX, '/_debug_toolbar'))
363 363
364 364 pyramid_app, _ = wrap_in_appenlight_if_enabled(pyramid_app, settings)
365 365
366 366 if settings['gzip_responses']:
367 367 pyramid_app = make_gzip_middleware(
368 368 pyramid_app, settings, compress_level=1)
369 369
370 370 # this should be the outer most middleware in the wsgi stack since
371 371 # middleware like Routes make database calls
372 372 def pyramid_app_with_cleanup(environ, start_response):
373 373 try:
374 374 return pyramid_app(environ, start_response)
375 375 finally:
376 376 # Dispose current database session and rollback uncommitted
377 377 # transactions.
378 378 meta.Session.remove()
379 379
380 380 # In a single threaded mode server, on non sqlite db we should have
381 381 # '0 Current Checked out connections' at the end of a request,
382 382 # if not, then something, somewhere is leaving a connection open
383 383 pool = meta.Base.metadata.bind.engine.pool
384 384 log.debug('sa pool status: %s', pool.status())
385 385
386 386
387 387 return pyramid_app_with_cleanup
388 388
389 389
390 390 def sanitize_settings_and_apply_defaults(settings):
391 391 """
392 392 Applies settings defaults and does all type conversion.
393 393
394 394 We would move all settings parsing and preparation into this place, so that
395 395 we have only one place left which deals with this part. The remaining parts
396 396 of the application would start to rely fully on well prepared settings.
397 397
398 398 This piece would later be split up per topic to avoid a big fat monster
399 399 function.
400 400 """
401 401
402 402 # Pyramid's mako renderer has to search in the templates folder so that the
403 403 # old templates still work. Ported and new templates are expected to use
404 404 # real asset specifications for the includes.
405 405 mako_directories = settings.setdefault('mako.directories', [
406 406 # Base templates of the original Pylons application
407 407 'rhodecode:templates',
408 408 ])
409 409 log.debug(
410 410 "Using the following Mako template directories: %s",
411 411 mako_directories)
412 412
413 413 # Default includes, possible to change as a user
414 414 pyramid_includes = settings.setdefault('pyramid.includes', [
415 415 'rhodecode.lib.middleware.request_wrapper',
416 416 ])
417 417 log.debug(
418 418 "Using the following pyramid.includes: %s",
419 419 pyramid_includes)
420 420
421 421 # TODO: johbo: Re-think this, usually the call to config.include
422 422 # should allow to pass in a prefix.
423 423 settings.setdefault('rhodecode.api.url', '/_admin/api')
424 424
425 425 # Sanitize generic settings.
426 426 _list_setting(settings, 'default_encoding', 'UTF-8')
427 427 _bool_setting(settings, 'is_test', 'false')
428 428 _bool_setting(settings, 'gzip_responses', 'false')
429 429
430 430 # Call split out functions that sanitize settings for each topic.
431 431 _sanitize_appenlight_settings(settings)
432 432 _sanitize_vcs_settings(settings)
433 433
434 434 return settings
435 435
436 436
437 437 def _sanitize_appenlight_settings(settings):
438 438 _bool_setting(settings, 'appenlight', 'false')
439 439
440 440
441 441 def _sanitize_vcs_settings(settings):
442 442 """
443 443 Applies settings defaults and does type conversion for all VCS related
444 444 settings.
445 445 """
446 446 _string_setting(settings, 'vcs.svn.compatible_version', '')
447 447 _string_setting(settings, 'git_rev_filter', '--all')
448 448 _string_setting(settings, 'vcs.hooks.protocol', 'http')
449 449 _string_setting(settings, 'vcs.scm_app_implementation', 'http')
450 450 _string_setting(settings, 'vcs.server', '')
451 451 _string_setting(settings, 'vcs.server.log_level', 'debug')
452 452 _string_setting(settings, 'vcs.server.protocol', 'http')
453 453 _bool_setting(settings, 'startup.import_repos', 'false')
454 454 _bool_setting(settings, 'vcs.hooks.direct_calls', 'false')
455 455 _bool_setting(settings, 'vcs.server.enable', 'true')
456 456 _bool_setting(settings, 'vcs.start_server', 'false')
457 457 _list_setting(settings, 'vcs.backends', 'hg, git, svn')
458 458 _int_setting(settings, 'vcs.connection_timeout', 3600)
459 459
460 460 # Support legacy values of vcs.scm_app_implementation. Legacy
461 461 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http'
462 462 # which is now mapped to 'http'.
463 463 scm_app_impl = settings['vcs.scm_app_implementation']
464 464 if scm_app_impl == 'rhodecode.lib.middleware.utils.scm_app_http':
465 465 settings['vcs.scm_app_implementation'] = 'http'
466 466
467 467
468 468 def _int_setting(settings, name, default):
469 469 settings[name] = int(settings.get(name, default))
470 470
471 471
472 472 def _bool_setting(settings, name, default):
473 473 input = settings.get(name, default)
474 474 if isinstance(input, unicode):
475 475 input = input.encode('utf8')
476 476 settings[name] = asbool(input)
477 477
478 478
479 479 def _list_setting(settings, name, default):
480 480 raw_value = settings.get(name, default)
481 481
482 482 old_separator = ','
483 483 if old_separator in raw_value:
484 484 # If we get a comma separated list, pass it to our own function.
485 485 settings[name] = rhodecode_aslist(raw_value, sep=old_separator)
486 486 else:
487 487 # Otherwise we assume it uses pyramids space/newline separation.
488 488 settings[name] = aslist(raw_value)
489 489
490 490
491 491 def _string_setting(settings, name, default, lower=True):
492 492 value = settings.get(name, default)
493 493 if lower:
494 494 value = value.lower()
495 495 settings[name] = value
General Comments 0
You need to be logged in to leave comments. Login now