示例#1
0
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[str('HTTPS')] = str('on')
    else:
        os.environ[str('HTTPS')] = str('off')

    # Migrate over any legacy avatar backend settings.
    if avatar_services.migrate_settings(siteconfig):
        dirty = True

    # Save back changes if they have been made
    if dirty:
        siteconfig.save()

    # Reload privacy consent requirements
    recompute_privacy_consents()

    site_settings_loaded.send(sender=None)

    return siteconfig
示例#2
0
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[str('HTTPS')] = str('on')
    else:
        os.environ[str('HTTPS')] = str('off')

    # Migrate over any legacy avatar backend settings.
    if avatar_services.migrate_settings(siteconfig):
        dirty = True

    # Save back changes if they have been made
    if dirty:
        siteconfig.save()

    # Reload privacy consent requirements
    recompute_privacy_consents()

    site_settings_loaded.send(sender=None)

    return siteconfig