settings.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. #!/usr/bin/env python
  2. # Licensed to Cloudera, Inc. under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. Cloudera, Inc. licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. # Django settings for Hue.
  18. #
  19. # Local customizations are done by symlinking a file
  20. # as local_settings.py.
  21. import logging
  22. import os
  23. import pkg_resources
  24. import sys
  25. from guppy import hpy
  26. from django.utils.translation import ugettext_lazy as _
  27. import desktop.redaction
  28. from desktop.lib.paths import get_desktop_root
  29. from desktop.lib.python_util import force_dict_to_strings
  30. from aws.conf import is_enabled as is_s3_enabled
  31. # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
  32. BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), '..', '..', '..'))
  33. HUE_DESKTOP_VERSION = pkg_resources.get_distribution("desktop").version or "Unknown"
  34. NICE_NAME = "Hue"
  35. ENV_HUE_PROCESS_NAME = "HUE_PROCESS_NAME"
  36. ENV_DESKTOP_DEBUG = "DESKTOP_DEBUG"
  37. ############################################################
  38. # Part 1: Logging and imports.
  39. ############################################################
  40. # Configure debug mode
  41. DEBUG = True
  42. TEMPLATE_DEBUG = DEBUG
  43. # Start basic logging as soon as possible.
  44. if ENV_HUE_PROCESS_NAME not in os.environ:
  45. _proc = os.path.basename(len(sys.argv) > 1 and sys.argv[1] or sys.argv[0])
  46. os.environ[ENV_HUE_PROCESS_NAME] = _proc
  47. desktop.log.basic_logging(os.environ[ENV_HUE_PROCESS_NAME])
  48. logging.info("Welcome to Hue " + HUE_DESKTOP_VERSION)
  49. # Then we can safely import some more stuff
  50. from desktop import appmanager
  51. from desktop.lib import conf
  52. # Add fancy logging
  53. desktop.log.fancy_logging()
  54. ############################################################
  55. # Part 2: Generic Configuration
  56. ############################################################
  57. # Language code for this installation. All choices can be found here:
  58. # http://www.i18nguy.com/unicode/language-identifiers.html
  59. LANGUAGE_CODE = 'en-us'
  60. LANGUAGES = [
  61. ('de', _('German')),
  62. ('en-us', _('English')),
  63. ('es', _('Spanish')),
  64. ('fr', _('French')),
  65. ('ja', _('Japanese')),
  66. ('ko', _('Korean')),
  67. ('pt', _('Portuguese')),
  68. ('pt_BR', _('Brazilian Portuguese')),
  69. ('zh_CN', _('Simplified Chinese')),
  70. ]
  71. SITE_ID = 1
  72. # If you set this to False, Django will make some optimizations so as not
  73. # to load the internationalization machinery.
  74. USE_I18N = True
  75. # If you set this to False, Django will not format dates, numbers and
  76. # calendars according to the current locale.
  77. USE_L10N = True
  78. # If you set this to False, Django will not use timezone-aware datetimes.
  79. USE_TZ = False
  80. # URL that handles the media served from MEDIA_ROOT. Make sure to use a
  81. # trailing slash.
  82. # Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
  83. MEDIA_URL = ''
  84. ############################################################
  85. # Part 3: Django configuration
  86. ############################################################
  87. # Additional locations of static files
  88. STATICFILES_DIRS = (
  89. os.path.join(BASE_DIR, 'desktop', 'libs', 'indexer', 'src', 'indexer', 'static'),
  90. os.path.join(BASE_DIR, 'desktop', 'libs', 'notebook', 'src', 'notebook', 'static'),
  91. os.path.join(BASE_DIR, 'desktop', 'libs', 'liboauth', 'src', 'liboauth', 'static'),
  92. )
  93. STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.CachedStaticFilesStorage'
  94. # For Django admin interface
  95. STATIC_URL = '/static/'
  96. STATIC_ROOT = os.path.join(BASE_DIR, 'build', 'static')
  97. # List of callables that know how to import templates from various sources.
  98. TEMPLATE_LOADERS = (
  99. 'django.template.loaders.filesystem.Loader',
  100. 'django.template.loaders.app_directories.Loader'
  101. )
  102. MIDDLEWARE_CLASSES = [
  103. # The order matters
  104. 'desktop.middleware.MetricsMiddleware',
  105. 'desktop.middleware.EnsureSafeMethodMiddleware',
  106. 'desktop.middleware.AuditLoggingMiddleware',
  107. 'django.middleware.common.CommonMiddleware',
  108. 'django.contrib.sessions.middleware.SessionMiddleware',
  109. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  110. 'desktop.middleware.SpnegoMiddleware',
  111. 'desktop.middleware.HueRemoteUserMiddleware',
  112. 'django.middleware.locale.LocaleMiddleware',
  113. 'babeldjango.middleware.LocaleMiddleware',
  114. 'desktop.middleware.AjaxMiddleware',
  115. 'django.middleware.security.SecurityMiddleware',
  116. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  117. 'desktop.middleware.ContentSecurityPolicyMiddleware',
  118. # Must be after Session, Auth, and Ajax. Before everything else.
  119. 'desktop.middleware.LoginAndPermissionMiddleware',
  120. 'django.contrib.messages.middleware.MessageMiddleware',
  121. 'desktop.middleware.NotificationMiddleware',
  122. 'desktop.middleware.ExceptionMiddleware',
  123. 'desktop.middleware.ClusterMiddleware',
  124. # 'debug_toolbar.middleware.DebugToolbarMiddleware'
  125. 'django.middleware.csrf.CsrfViewMiddleware',
  126. 'django.middleware.http.ConditionalGetMiddleware',
  127. 'axes.middleware.FailedLoginMiddleware',
  128. 'desktop.middleware.MimeTypeJSFileFixStreamingMiddleware',
  129. ]
  130. # if os.environ.get(ENV_DESKTOP_DEBUG):
  131. # MIDDLEWARE_CLASSES.append('desktop.middleware.HtmlValidationMiddleware')
  132. # logging.debug("Will try to validate generated HTML.")
  133. ROOT_URLCONF = 'desktop.urls'
  134. # Hue runs its own wsgi applications
  135. WSGI_APPLICATION = None
  136. TEMPLATE_DIRS = (
  137. get_desktop_root("core/templates"),
  138. )
  139. INSTALLED_APPS = [
  140. 'django.contrib.auth',
  141. 'django_openid_auth',
  142. 'django.contrib.contenttypes',
  143. 'django.contrib.sessions',
  144. 'django.contrib.sites',
  145. 'django.contrib.staticfiles',
  146. 'django.contrib.admin',
  147. 'django_extensions',
  148. # 'debug_toolbar',
  149. 'south', # database migration tool
  150. # i18n support
  151. 'babeldjango',
  152. # Desktop injects all the other installed apps into here magically.
  153. 'desktop',
  154. # App that keeps track of failed logins.
  155. 'axes',
  156. ]
  157. LOCALE_PATHS = [
  158. get_desktop_root('core/src/desktop/locale')
  159. ]
  160. # Keep default values up to date
  161. TEMPLATE_CONTEXT_PROCESSORS = (
  162. 'django.contrib.auth.context_processors.auth',
  163. 'django.core.context_processors.debug',
  164. 'django.core.context_processors.i18n',
  165. 'django.core.context_processors.media',
  166. 'django.core.context_processors.request',
  167. 'django.contrib.messages.context_processors.messages',
  168. # Not default
  169. 'desktop.context_processors.app_name',
  170. )
  171. # Desktop doesn't use an auth profile module, because
  172. # because it doesn't mesh very well with the notion
  173. # of having multiple apps. If your app needs
  174. # to store data related to users, it should
  175. # manage its own table with an appropriate foreign key.
  176. AUTH_PROFILE_MODULE = None
  177. LOGIN_REDIRECT_URL = "/"
  178. LOGOUT_REDIRECT_URL = "/" # For djangosaml2 bug.
  179. PYLINTRC = get_desktop_root('.pylintrc')
  180. # Custom CSRF Failure View
  181. CSRF_FAILURE_VIEW = 'desktop.views.csrf_failure'
  182. ############################################################
  183. # Part 4: Installation of apps
  184. ############################################################
  185. _config_dir = os.getenv("HUE_CONF_DIR", get_desktop_root("conf"))
  186. # Libraries are loaded and configured before the apps
  187. appmanager.load_libs()
  188. _lib_conf_modules = [dict(module=app.conf, config_key=None) for app in appmanager.DESKTOP_LIBS if app.conf is not None]
  189. LOCALE_PATHS.extend([app.locale_path for app in appmanager.DESKTOP_LIBS])
  190. # Load desktop config
  191. _desktop_conf_modules = [dict(module=desktop.conf, config_key=None)]
  192. conf.initialize(_desktop_conf_modules, _config_dir)
  193. # Register the redaction filters into the root logger as soon as possible.
  194. desktop.redaction.register_log_filtering(desktop.conf.get_redaction_policy())
  195. # Activate l10n
  196. # Install apps
  197. appmanager.load_apps(desktop.conf.APP_BLACKLIST.get())
  198. for app in appmanager.DESKTOP_APPS:
  199. INSTALLED_APPS.extend(app.django_apps)
  200. LOCALE_PATHS.append(app.locale_path)
  201. logging.debug("Installed Django modules: %s" % ",".join(map(str, appmanager.DESKTOP_MODULES)))
  202. # Load app configuration
  203. _app_conf_modules = [dict(module=app.conf, config_key=app.config_key) for app in appmanager.DESKTOP_APPS if app.conf is not None]
  204. conf.initialize(_lib_conf_modules, _config_dir)
  205. conf.initialize(_app_conf_modules, _config_dir)
  206. # Now that we've loaded the desktop conf, set the django DEBUG mode based on the conf.
  207. DEBUG = desktop.conf.DJANGO_DEBUG_MODE.get()
  208. TEMPLATE_DEBUG = DEBUG
  209. if DEBUG: # For simplification, force all DEBUG when django_debug_mode is True and re-apply the loggers
  210. os.environ[ENV_DESKTOP_DEBUG] = 'True'
  211. desktop.log.basic_logging(os.environ[ENV_HUE_PROCESS_NAME])
  212. desktop.log.fancy_logging()
  213. ############################################################
  214. # Part 4a: Django configuration that requires bound Desktop
  215. # configs.
  216. ############################################################
  217. # Configure allowed hosts
  218. ALLOWED_HOSTS = desktop.conf.ALLOWED_HOSTS.get()
  219. X_FRAME_OPTIONS = desktop.conf.X_FRAME_OPTIONS.get()
  220. # Configure hue admins
  221. ADMINS = []
  222. for admin in desktop.conf.DJANGO_ADMINS.get():
  223. admin_conf = desktop.conf.DJANGO_ADMINS[admin]
  224. if 'name' in admin_conf.bind_to and 'email' in admin_conf.bind_to:
  225. ADMINS.append(((admin_conf.NAME.get(), admin_conf.EMAIL.get())))
  226. ADMINS = tuple(ADMINS)
  227. MANAGERS = ADMINS
  228. # Server Email Address
  229. SERVER_EMAIL = desktop.conf.DJANGO_SERVER_EMAIL.get()
  230. # Email backend
  231. EMAIL_BACKEND = desktop.conf.DJANGO_EMAIL_BACKEND.get()
  232. # Configure database
  233. if os.getenv('DESKTOP_DB_CONFIG'):
  234. conn_string = os.getenv('DESKTOP_DB_CONFIG')
  235. logging.debug("DESKTOP_DB_CONFIG SET: %s" % (conn_string))
  236. default_db = dict(zip(
  237. ["ENGINE", "NAME", "TEST_NAME", "USER", "PASSWORD", "HOST", "PORT"],
  238. conn_string.split(':')))
  239. default_db['NAME'] = default_db['NAME'].replace('#', ':') # For is_db_alive command
  240. else:
  241. test_name = os.environ.get('DESKTOP_DB_TEST_NAME', get_desktop_root('desktop-test.db'))
  242. logging.debug("DESKTOP_DB_TEST_NAME SET: %s" % test_name)
  243. test_user = os.environ.get('DESKTOP_DB_TEST_USER', 'hue_test')
  244. logging.debug("DESKTOP_DB_TEST_USER SET: %s" % test_user)
  245. default_db = {
  246. "ENGINE" : desktop.conf.DATABASE.ENGINE.get(),
  247. "NAME" : desktop.conf.DATABASE.NAME.get(),
  248. "USER" : desktop.conf.DATABASE.USER.get(),
  249. "SCHEMA" : desktop.conf.DATABASE.SCHEMA.get(),
  250. "PASSWORD" : desktop.conf.get_database_password(),
  251. "HOST" : desktop.conf.DATABASE.HOST.get(),
  252. "PORT" : str(desktop.conf.DATABASE.PORT.get()),
  253. "OPTIONS": force_dict_to_strings(desktop.conf.DATABASE.OPTIONS.get()),
  254. # DB used for tests
  255. "TEST_NAME" : test_name,
  256. "TEST_USER" : test_user,
  257. # Wrap each request in a transaction.
  258. "ATOMIC_REQUESTS" : True,
  259. "CONN_MAX_AGE" : desktop.conf.DATABASE.CONN_MAX_AGE.get(),
  260. }
  261. DATABASES = {
  262. 'default': default_db
  263. }
  264. CACHES = {
  265. 'default': {
  266. 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
  267. 'LOCATION': 'unique-hue'
  268. }
  269. }
  270. # Configure sessions
  271. SESSION_COOKIE_NAME = desktop.conf.SESSION.COOKIE_NAME.get()
  272. SESSION_COOKIE_AGE = desktop.conf.SESSION.TTL.get()
  273. SESSION_COOKIE_SECURE = desktop.conf.SESSION.SECURE.get()
  274. SESSION_EXPIRE_AT_BROWSER_CLOSE = desktop.conf.SESSION.EXPIRE_AT_BROWSER_CLOSE.get()
  275. # HTTP only
  276. SESSION_COOKIE_HTTPONLY = desktop.conf.SESSION.HTTP_ONLY.get()
  277. CSRF_COOKIE_SECURE = desktop.conf.SESSION.SECURE.get()
  278. CSRF_COOKIE_HTTPONLY = desktop.conf.SESSION.HTTP_ONLY.get()
  279. CSRF_COOKIE_NAME='csrftoken'
  280. SECURE_HSTS_SECONDS = desktop.conf.SECURE_HSTS_SECONDS.get()
  281. SECURE_HSTS_INCLUDE_SUBDOMAINS = desktop.conf.SECURE_HSTS_INCLUDE_SUBDOMAINS.get()
  282. SECURE_CONTENT_TYPE_NOSNIFF = desktop.conf.SECURE_CONTENT_TYPE_NOSNIFF.get()
  283. SECURE_BROWSER_XSS_FILTER = desktop.conf.SECURE_BROWSER_XSS_FILTER.get()
  284. SECURE_SSL_REDIRECT = desktop.conf.SECURE_SSL_REDIRECT.get()
  285. SECURE_SSL_HOST = desktop.conf.SECURE_SSL_HOST.get()
  286. SECURE_REDIRECT_EXEMPT = desktop.conf.SECURE_REDIRECT_EXEMPT.get()
  287. # django-nose test specifics
  288. TEST_RUNNER = 'desktop.lib.test_runners.HueTestRunner'
  289. # Turn off cache middleware
  290. if 'test' in sys.argv:
  291. CACHE_MIDDLEWARE_SECONDS = 0
  292. # Limit Nose coverage to Hue apps
  293. NOSE_ARGS = [
  294. '--cover-package=%s' % ','.join([app.name for app in appmanager.DESKTOP_APPS + appmanager.DESKTOP_LIBS]),
  295. '--no-path-adjustment',
  296. '--traverse-namespace'
  297. ]
  298. TIME_ZONE = desktop.conf.TIME_ZONE.get()
  299. if desktop.conf.DEMO_ENABLED.get():
  300. AUTHENTICATION_BACKENDS = ('desktop.auth.backend.DemoBackend',)
  301. elif desktop.conf.IS_EMBEDDED.get():
  302. AUTHENTICATION_BACKENDS = ('desktop.auth.backend.ImpersonationBackend',)
  303. else:
  304. AUTHENTICATION_BACKENDS = tuple(desktop.conf.AUTH.BACKEND.get())
  305. EMAIL_HOST = desktop.conf.SMTP.HOST.get()
  306. EMAIL_PORT = desktop.conf.SMTP.PORT.get()
  307. EMAIL_HOST_USER = desktop.conf.SMTP.USER.get()
  308. EMAIL_HOST_PASSWORD = desktop.conf.get_smtp_password()
  309. EMAIL_USE_TLS = desktop.conf.SMTP.USE_TLS.get()
  310. DEFAULT_FROM_EMAIL = desktop.conf.SMTP.DEFAULT_FROM.get()
  311. # Used for securely creating sessions. Should be unique and not shared with anybody. Changing auth backends will invalidate all open sessions.
  312. SECRET_KEY = desktop.conf.get_secret_key()
  313. if SECRET_KEY:
  314. SECRET_KEY += str(AUTHENTICATION_BACKENDS)
  315. else:
  316. import uuid
  317. SECRET_KEY = str(uuid.uuid4())
  318. # Axes
  319. AXES_LOGIN_FAILURE_LIMIT = desktop.conf.AUTH.LOGIN_FAILURE_LIMIT.get()
  320. AXES_LOCK_OUT_AT_FAILURE = desktop.conf.AUTH.LOGIN_LOCK_OUT_AT_FAILURE.get()
  321. AXES_COOLOFF_TIME = None
  322. if desktop.conf.AUTH.LOGIN_COOLOFF_TIME.get() and desktop.conf.AUTH.LOGIN_COOLOFF_TIME.get() != 0:
  323. AXES_COOLOFF_TIME = desktop.conf.AUTH.LOGIN_COOLOFF_TIME.get()
  324. AXES_USE_USER_AGENT = desktop.conf.AUTH.LOGIN_LOCK_OUT_USE_USER_AGENT.get()
  325. AXES_LOCK_OUT_BY_COMBINATION_USER_AND_IP = desktop.conf.AUTH.LOGIN_LOCK_OUT_BY_COMBINATION_USER_AND_IP.get()
  326. AXES_BEHIND_REVERSE_PROXY = desktop.conf.AUTH.BEHIND_REVERSE_PROXY.get()
  327. AXES_REVERSE_PROXY_HEADER = desktop.conf.AUTH.REVERSE_PROXY_HEADER.get()
  328. LOGIN_URL = '/hue/accounts/login'
  329. # SAML
  330. SAML_AUTHENTICATION = 'libsaml.backend.SAML2Backend' in AUTHENTICATION_BACKENDS
  331. if SAML_AUTHENTICATION:
  332. from libsaml.saml_settings import *
  333. INSTALLED_APPS.append('libsaml')
  334. LOGIN_URL = '/saml2/login/'
  335. SESSION_EXPIRE_AT_BROWSER_CLOSE = True
  336. # Middleware classes.
  337. for middleware in desktop.conf.MIDDLEWARE.get():
  338. MIDDLEWARE_CLASSES.append(middleware)
  339. # OpenId
  340. OPENID_AUTHENTICATION = 'libopenid.backend.OpenIDBackend' in AUTHENTICATION_BACKENDS
  341. if OPENID_AUTHENTICATION:
  342. from libopenid.openid_settings import *
  343. INSTALLED_APPS.append('libopenid')
  344. LOGIN_URL = '/openid/login'
  345. SESSION_EXPIRE_AT_BROWSER_CLOSE = True
  346. # OAuth
  347. OAUTH_AUTHENTICATION='liboauth.backend.OAuthBackend' in AUTHENTICATION_BACKENDS
  348. if OAUTH_AUTHENTICATION:
  349. INSTALLED_APPS.append('liboauth')
  350. LOGIN_URL = '/oauth/accounts/login'
  351. SESSION_EXPIRE_AT_BROWSER_CLOSE = True
  352. # URL Redirection white list.
  353. if desktop.conf.REDIRECT_WHITELIST.get():
  354. MIDDLEWARE_CLASSES.append('desktop.middleware.EnsureSafeRedirectURLMiddleware')
  355. # Enable X-Forwarded-Host header if the load balancer requires it
  356. USE_X_FORWARDED_HOST = desktop.conf.USE_X_FORWARDED_HOST.get()
  357. # Support HTTPS load-balancing
  358. if desktop.conf.SECURE_PROXY_SSL_HEADER.get():
  359. SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
  360. # Add last activity tracking and idle session timeout
  361. if 'useradmin' in [app.name for app in appmanager.DESKTOP_APPS]:
  362. MIDDLEWARE_CLASSES.append('useradmin.middleware.LastActivityMiddleware')
  363. if desktop.conf.SESSION.CONCURRENT_USER_SESSION_LIMIT.get():
  364. MIDDLEWARE_CLASSES.append('useradmin.middleware.ConcurrentUserSessionMiddleware')
  365. LOAD_BALANCER_COOKIE = 'ROUTEID'
  366. ################################################################
  367. # Register file upload handlers
  368. # This section must go after the desktop lib modules are loaded
  369. ################################################################
  370. # Insert our custom upload handlers
  371. file_upload_handlers = [
  372. 'hadoop.fs.upload.HDFSfileUploadHandler',
  373. 'django.core.files.uploadhandler.MemoryFileUploadHandler',
  374. 'django.core.files.uploadhandler.TemporaryFileUploadHandler',
  375. ]
  376. if is_s3_enabled():
  377. file_upload_handlers.insert(0, 'aws.s3.upload.S3FileUploadHandler')
  378. FILE_UPLOAD_HANDLERS = tuple(file_upload_handlers)
  379. ############################################################
  380. # Necessary for South to not fuzz with tests. Fixed in South 0.7.1
  381. SKIP_SOUTH_TESTS = True
  382. # Set up environment variable so Kerberos libraries look at our private
  383. # ticket cache
  384. os.environ['KRB5CCNAME'] = desktop.conf.KERBEROS.CCACHE_PATH.get()
  385. if not os.getenv('SERVER_SOFTWARE'):
  386. os.environ['SERVER_SOFTWARE'] = 'apache'
  387. # If Hue is configured to use a CACERTS truststore, make sure that the
  388. # REQUESTS_CA_BUNDLE is set so that we can use it when we make external requests.
  389. # This is for the REST calls made by Hue with the requests library.
  390. if desktop.conf.SSL_CACERTS.get() and os.environ.get('REQUESTS_CA_BUNDLE') is None:
  391. os.environ['REQUESTS_CA_BUNDLE'] = desktop.conf.SSL_CACERTS.get()
  392. # Preventing local build failure by not validating the default value of REQUESTS_CA_BUNDLE
  393. if os.environ.get('REQUESTS_CA_BUNDLE') and os.environ.get('REQUESTS_CA_BUNDLE') != desktop.conf.SSL_CACERTS.config.default and not os.path.isfile(os.environ['REQUESTS_CA_BUNDLE']):
  394. raise Exception(_('SSL Certificate pointed by REQUESTS_CA_BUNDLE does not exist: %s') % os.environ['REQUESTS_CA_BUNDLE'])
  395. # Memory
  396. if desktop.conf.MEMORY_PROFILER.get():
  397. MEMORY_PROFILER = hpy()
  398. MEMORY_PROFILER.setrelheap()
  399. if not desktop.conf.DATABASE_LOGGING.get():
  400. def disable_database_logging():
  401. from django.db.backends import BaseDatabaseWrapper
  402. from django.db.backends.util import CursorWrapper
  403. BaseDatabaseWrapper.make_debug_cursor = lambda self, cursor: CursorWrapper(cursor, self)
  404. disable_database_logging()
  405. ############################################################
  406. # Searching saved documents in Oracle returns following error:
  407. # DatabaseError: ORA-06502: PL/SQL: numeric or value error: character string buffer too small
  408. # This is caused by DBMS_LOB.SUBSTR(%s, 4000) in Django framework django/db/backends/oracle/base.py
  409. # Django has a ticket for this issue but unfixed: https://code.djangoproject.com/ticket/11580.
  410. # Buffer size 4000 limit the length of field equals or less than 2000 characters.
  411. #
  412. # For performance reasons and to avoid searching in huge fields, we also truncate to a max length
  413. DOCUMENT2_SEARCH_MAX_LENGTH = 2000