def load_site_config(full_reload=False): """Load stored site configuration settings. This populates the Django settings object with any keys that need to be there. """ global _original_webapi_auth_backends def apply_setting(settings_key, db_key, default=None): """Apply the given siteconfig value to the Django settings object.""" db_value = siteconfig.settings.get(db_key) if db_value: setattr(settings, settings_key, db_value) elif default: setattr(settings, settings_key, default) def update_haystack_settings(): """Update the haystack settings in site config.""" search_backend_id = (siteconfig.get('search_backend_id') or defaults['search_backend_id']) search_backend = search_backend_registry.get_search_backend( search_backend_id) if not search_backend: raise ImproperlyConfigured( _('The search engine "%s" could not be found. If this is ' 'provided by an extension, you will have to make sure that ' 'extension is enabled.' % search_backend_id)) apply_setting('HAYSTACK_CONNECTIONS', None, { 'default': search_backend.configuration, }) # Re-initialize Haystack's connection information to use the updated # settings. connections.connections_info = settings.HAYSTACK_CONNECTIONS connections._connections = {} # If siteconfig needs to be saved back to the DB, set dirty=true dirty = False try: siteconfig = SiteConfiguration.objects.get_current() except SiteConfiguration.DoesNotExist: raise ImproperlyConfigured( "The site configuration entry does not exist in the database. " "Re-run `./manage.py` syncdb to fix this.") except Exception as e: # We got something else. Likely, this doesn't exist yet and we're # doing a syncdb or something, so silently ignore. logging.error('Could not load siteconfig: %s' % e) return # Populate defaults if they weren't already set. if not siteconfig.get_defaults(): siteconfig.add_defaults(defaults) # The default value for DEFAULT_EMAIL_FROM (webmaster@localhost) # is less than good, so use a better one if it's set to that or if # we haven't yet set this value in siteconfig. mail_default_from = \ siteconfig.settings.get('mail_default_from', global_settings.DEFAULT_FROM_EMAIL) if (not mail_default_from or mail_default_from == global_settings.DEFAULT_FROM_EMAIL): domain = siteconfig.site.domain.split(':')[0] siteconfig.set('mail_default_from', 'noreply@' + domain) # STATIC_* and MEDIA_* must be different paths, and differ in meaning. # If site_static_* is empty or equal to media_static_*, we're probably # migrating from an earlier Review Board install. site_static_root = siteconfig.settings.get('site_static_root', '') site_media_root = siteconfig.settings.get('site_media_root') if site_static_root == '' or site_static_root == site_media_root: siteconfig.set('site_static_root', settings.STATIC_ROOT) site_static_url = siteconfig.settings.get('site_static_url', '') site_media_url = siteconfig.settings.get('site_media_url') if site_static_url == '' or site_static_url == site_media_url: siteconfig.set('site_static_url', settings.STATIC_URL) # Populate the settings object with anything relevant from the siteconfig. apply_django_settings(siteconfig, settings_map) if full_reload and not getattr(settings, 'RUNNING_TEST', False): # Logging may have changed, so restart logging. restart_logging() # Now for some more complicated stuff... update_haystack_settings() # Site administrator settings apply_setting("ADMINS", None, ((siteconfig.get( "site_admin_name", ""), siteconfig.get("site_admin_email", "")), )) apply_setting("MANAGERS", None, settings.ADMINS) # Explicitly base this off the STATIC_URL apply_setting("ADMIN_MEDIA_PREFIX", None, settings.STATIC_URL + "admin/") # Set the auth backends auth_backend_id = siteconfig.settings.get("auth_backend", "builtin") builtin_backend_obj = auth_backends.get('backend_id', 'builtin') builtin_backend = "%s.%s" % (builtin_backend_obj.__module__, builtin_backend_obj.__name__) if auth_backend_id == "custom": custom_backends = siteconfig.settings.get("auth_custom_backends") if isinstance(custom_backends, six.string_types): custom_backends = (custom_backends, ) elif isinstance(custom_backends, list): custom_backends = tuple(custom_backends) settings.AUTHENTICATION_BACKENDS = custom_backends if builtin_backend not in custom_backends: settings.AUTHENTICATION_BACKENDS += (builtin_backend, ) else: backend = auth_backends.get('backend_id', auth_backend_id) if backend and backend is not builtin_backend_obj: settings.AUTHENTICATION_BACKENDS = \ ("%s.%s" % (backend.__module__, backend.__name__), builtin_backend) else: settings.AUTHENTICATION_BACKENDS = (builtin_backend, ) # If we're upgrading from a 1.x LDAP configuration, populate # ldap_uid and clear ldap_uid_mask if auth_backend_id == "ldap": if not hasattr(settings, 'LDAP_UID'): if hasattr(settings, 'LDAP_UID_MASK'): # Get the username attribute from the old UID mask # LDAP attributes can contain only alphanumeric # characters and the hyphen and must lead with an # alphabetic character. This is not dependent upon # locale. m = re.search("([a-zA-Z][a-zA-Z0-9-]+)=%s", settings.LDAP_UID_MASK) if m: # Assign LDAP_UID the value of the retrieved attribute settings.LDAP_UID = m.group(1) else: # Couldn't match the old value? # This should be impossible, but in this case, let's # just guess a sane default and hope for the best. settings.LDAP_UID = 'uid' else: # Neither the old nor new value? # This should be impossible, but in this case, let's just # guess a sane default and hope for the best. settings.LDAP_UID = 'uid' # Remove the LDAP_UID_MASK value settings.LDAP_UID_MASK = None siteconfig.set('auth_ldap_uid', settings.LDAP_UID) siteconfig.set('auth_ldap_uid_mask', settings.LDAP_UID_MASK) # Set the dirty flag so we save this back dirty = True # Add APITokenBackend to the list of auth backends. This one is always # present, and is used only for API requests. settings.AUTHENTICATION_BACKENDS += ( 'reviewboard.webapi.auth_backends.TokenAuthBackend', ) # Reset the WebAPI auth backends in case OAuth2 has become disabled. settings.WEB_API_AUTH_BACKENDS = _original_webapi_auth_backends reset_auth_backends() if oauth2_service_feature.is_enabled(): settings.AUTHENTICATION_BACKENDS += ( 'reviewboard.webapi.auth_backends.OAuth2TokenAuthBackend', ) settings.WEB_API_AUTH_BACKENDS += ( 'djblets.webapi.auth.backends.oauth2_tokens' '.WebAPIOAuth2TokenAuthBackend', ) # Set the storage backend storage_backend = siteconfig.settings.get('storage_backend', 'builtin') if storage_backend in storage_backend_map: settings.DEFAULT_FILE_STORAGE = storage_backend_map[storage_backend] else: settings.DEFAULT_FILE_STORAGE = storage_backend_map['builtin'] # These blow up if they're not the perfectly right types settings.AWS_QUERYSTRING_AUTH = siteconfig.get('aws_querystring_auth') settings.AWS_ACCESS_KEY_ID = six.text_type( siteconfig.get('aws_access_key_id')) settings.AWS_SECRET_ACCESS_KEY = six.text_type( siteconfig.get('aws_secret_access_key')) settings.AWS_STORAGE_BUCKET_NAME = six.text_type( siteconfig.get('aws_s3_bucket_name')) try: settings.AWS_CALLING_FORMAT = int(siteconfig.get('aws_calling_format')) except ValueError: settings.AWS_CALLING_FORMAT = 0 settings.SWIFT_AUTH_URL = six.text_type(siteconfig.get('swift_auth_url')) settings.SWIFT_USERNAME = six.text_type(siteconfig.get('swift_username')) settings.SWIFT_KEY = six.text_type(siteconfig.get('swift_key')) try: settings.SWIFT_AUTH_VERSION = int(siteconfig.get('swift_auth_version')) except: settings.SWIFT_AUTH_VERSION = 1 settings.SWIFT_CONTAINER_NAME = six.text_type( siteconfig.get('swift_container_name')) if siteconfig.settings.get('site_domain_method', 'http') == 'https': os.environ[b'HTTPS'] = b'on' else: os.environ[b'HTTPS'] = b'off' # Save back changes if they have been made if dirty: siteconfig.save() site_settings_loaded.send(sender=None) return siteconfig
def load_site_config(full_reload=False): """Load stored site configuration settings. This populates the Django settings object with any keys that need to be there. """ global _original_webapi_auth_backends def apply_setting(settings_key, db_key, default=None): """Apply the given siteconfig value to the Django settings object.""" db_value = siteconfig.settings.get(db_key) if db_value: setattr(settings, settings_key, db_value) elif default: setattr(settings, settings_key, default) def update_haystack_settings(): """Update the haystack settings in site config.""" search_backend_id = (siteconfig.get('search_backend_id') or defaults['search_backend_id']) search_backend = search_backend_registry.get_search_backend( search_backend_id) if not search_backend: raise ImproperlyConfigured(_( 'The search engine "%s" could not be found. If this is ' 'provided by an extension, you will have to make sure that ' 'extension is enabled.' % search_backend_id )) apply_setting( 'HAYSTACK_CONNECTIONS', None, { 'default': search_backend.configuration, }) # Re-initialize Haystack's connection information to use the updated # settings. connections.connections_info = settings.HAYSTACK_CONNECTIONS connections._connections = {} # If siteconfig needs to be saved back to the DB, set dirty=true dirty = False try: siteconfig = SiteConfiguration.objects.get_current() except SiteConfiguration.DoesNotExist: raise ImproperlyConfigured( "The site configuration entry does not exist in the database. " "Re-run `./manage.py` syncdb to fix this.") except Exception as e: # We got something else. Likely, this doesn't exist yet and we're # doing a syncdb or something, so silently ignore. logging.error('Could not load siteconfig: %s' % e) return # Populate defaults if they weren't already set. if not siteconfig.get_defaults(): siteconfig.add_defaults(defaults) # The default value for DEFAULT_EMAIL_FROM (webmaster@localhost) # is less than good, so use a better one if it's set to that or if # we haven't yet set this value in siteconfig. mail_default_from = \ siteconfig.settings.get('mail_default_from', global_settings.DEFAULT_FROM_EMAIL) if (not mail_default_from or mail_default_from == global_settings.DEFAULT_FROM_EMAIL): domain = siteconfig.site.domain.split(':')[0] siteconfig.set('mail_default_from', 'noreply@' + domain) # STATIC_* and MEDIA_* must be different paths, and differ in meaning. # If site_static_* is empty or equal to media_static_*, we're probably # migrating from an earlier Review Board install. site_static_root = siteconfig.settings.get('site_static_root', '') site_media_root = siteconfig.settings.get('site_media_root') if site_static_root == '' or site_static_root == site_media_root: siteconfig.set('site_static_root', settings.STATIC_ROOT) site_static_url = siteconfig.settings.get('site_static_url', '') site_media_url = siteconfig.settings.get('site_media_url') if site_static_url == '' or site_static_url == site_media_url: siteconfig.set('site_static_url', settings.STATIC_URL) # Populate the settings object with anything relevant from the siteconfig. apply_django_settings(siteconfig, settings_map) if full_reload and not getattr(settings, 'RUNNING_TEST', False): # Logging may have changed, so restart logging. restart_logging() # Now for some more complicated stuff... update_haystack_settings() # Site administrator settings apply_setting("ADMINS", None, ( (siteconfig.get("site_admin_name", ""), siteconfig.get("site_admin_email", "")), )) apply_setting("MANAGERS", None, settings.ADMINS) # Explicitly base this off the STATIC_URL apply_setting("ADMIN_MEDIA_PREFIX", None, settings.STATIC_URL + "admin/") # Set the auth backends auth_backend_id = siteconfig.settings.get("auth_backend", "builtin") builtin_backend_obj = auth_backends.get('backend_id', 'builtin') builtin_backend = "%s.%s" % (builtin_backend_obj.__module__, builtin_backend_obj.__name__) if auth_backend_id == "custom": custom_backends = siteconfig.settings.get("auth_custom_backends") if isinstance(custom_backends, six.string_types): custom_backends = (custom_backends,) elif isinstance(custom_backends, list): custom_backends = tuple(custom_backends) settings.AUTHENTICATION_BACKENDS = custom_backends if builtin_backend not in custom_backends: settings.AUTHENTICATION_BACKENDS += (builtin_backend,) else: backend = auth_backends.get('backend_id', auth_backend_id) if backend and backend is not builtin_backend_obj: settings.AUTHENTICATION_BACKENDS = \ ("%s.%s" % (backend.__module__, backend.__name__), builtin_backend) else: settings.AUTHENTICATION_BACKENDS = (builtin_backend,) # If we're upgrading from a 1.x LDAP configuration, populate # ldap_uid and clear ldap_uid_mask if auth_backend_id == "ldap": if not hasattr(settings, 'LDAP_UID'): if hasattr(settings, 'LDAP_UID_MASK'): # Get the username attribute from the old UID mask # LDAP attributes can contain only alphanumeric # characters and the hyphen and must lead with an # alphabetic character. This is not dependent upon # locale. m = re.search("([a-zA-Z][a-zA-Z0-9-]+)=%s", settings.LDAP_UID_MASK) if m: # Assign LDAP_UID the value of the retrieved attribute settings.LDAP_UID = m.group(1) else: # Couldn't match the old value? # This should be impossible, but in this case, let's # just guess a sane default and hope for the best. settings.LDAP_UID = 'uid' else: # Neither the old nor new value? # This should be impossible, but in this case, let's just # guess a sane default and hope for the best. settings.LDAP_UID = 'uid' # Remove the LDAP_UID_MASK value settings.LDAP_UID_MASK = None siteconfig.set('auth_ldap_uid', settings.LDAP_UID) siteconfig.set('auth_ldap_uid_mask', settings.LDAP_UID_MASK) # Set the dirty flag so we save this back dirty = True # Add APITokenBackend to the list of auth backends. This one is always # present, and is used only for API requests. settings.AUTHENTICATION_BACKENDS += ( 'reviewboard.webapi.auth_backends.TokenAuthBackend', ) # Reset the WebAPI auth backends in case OAuth2 has become disabled. settings.WEB_API_AUTH_BACKENDS = _original_webapi_auth_backends reset_auth_backends() if oauth2_service_feature.is_enabled(): settings.AUTHENTICATION_BACKENDS += ( 'reviewboard.webapi.auth_backends.OAuth2TokenAuthBackend', ) settings.WEB_API_AUTH_BACKENDS += ( 'djblets.webapi.auth.backends.oauth2_tokens' '.WebAPIOAuth2TokenAuthBackend', ) # Set the storage backend storage_backend = siteconfig.settings.get('storage_backend', 'builtin') if storage_backend in storage_backend_map: settings.DEFAULT_FILE_STORAGE = storage_backend_map[storage_backend] else: settings.DEFAULT_FILE_STORAGE = storage_backend_map['builtin'] # These blow up if they're not the perfectly right types settings.AWS_QUERYSTRING_AUTH = siteconfig.get('aws_querystring_auth') settings.AWS_ACCESS_KEY_ID = six.text_type( siteconfig.get('aws_access_key_id')) settings.AWS_SECRET_ACCESS_KEY = six.text_type( siteconfig.get('aws_secret_access_key')) settings.AWS_STORAGE_BUCKET_NAME = six.text_type( siteconfig.get('aws_s3_bucket_name')) try: settings.AWS_CALLING_FORMAT = int(siteconfig.get('aws_calling_format')) except ValueError: settings.AWS_CALLING_FORMAT = 0 settings.SWIFT_AUTH_URL = six.text_type( siteconfig.get('swift_auth_url')) settings.SWIFT_USERNAME = six.text_type( siteconfig.get('swift_username')) settings.SWIFT_KEY = six.text_type( siteconfig.get('swift_key')) try: settings.SWIFT_AUTH_VERSION = int(siteconfig.get('swift_auth_version')) except: settings.SWIFT_AUTH_VERSION = 1 settings.SWIFT_CONTAINER_NAME = six.text_type( siteconfig.get('swift_container_name')) if siteconfig.settings.get('site_domain_method', 'http') == 'https': os.environ[b'HTTPS'] = b'on' else: os.environ[b'HTTPS'] = b'off' # Save back changes if they have been made if dirty: siteconfig.save() site_settings_loaded.send(sender=None) return siteconfig