<commit_before>import os

from django import conf
from django.utils.encoding import python_2_unicode_compatible

from secretkey import errors


class SecureSettings(conf.Settings):
    """
    Wraps a settings module so that SECRET_KEY cannot be set within the given
    settings module. Use this when configuring settings manually, otherwise use
    secretkey.settings.configure() in your manage.py and wsgi modules.

    The SECRET_KEY setting is loaded lazily in this class so that checks can be
    performed on the file first.
    """
    def __init__(self, settings_module):
        super(SecureSettings, self).__init__(settings_module)
        if not self.SECRET_KEY_FILE:
            raise conf.ImproperlyConfigured(
                "The SECRET_KEY_FILE setting must not be empty")

    def get_secret_key(self):
        try:
            with open(self.SECRET_KEY_FILE) as secret_key_file:
                return secret_key_file.read()
        except IOError as e:
            raise errors.SecretKeyFileNotFound(e)

    def _get_secret_key(self):
        # The super.__init__ method requires that SECRET_KEY is set, so give
        # it an object that will evaulate True when evaulated boolean-wise but
        # still cannot be evaulated as a string.
        if not conf.settings.configured:
            return UnusableSecretKey()
        if not hasattr(self, '_secret_key'):
            self._secret_key = self.get_secret_key()
        return self._secret_key

    def _set_secret_key(self, value):
        if not conf.settings.configured:
            return
        raise ValueError("The SECRET_KEY setting is read-only")

    def configure(self, **options):
        for name, value in options.iteritems():
            setattr(self, name, value)
        # Unfortunately LazySettings has no public API for extending the base
        # Settings class, so we have to override _wrapped here instead of
        # calling configure()
        conf.settings._wrapped = self

    SECRET_KEY = property(_get_secret_key, _set_secret_key)


@python_2_unicode_compatible
class UnusableSecretKey(object):
    def __str__(self):
        err = "SECRET_KEY cannot be used before settings are configured."
        raise ValueError(err)


def configure_secure():
    """
    Configures settings from DJANGO_SETTINGS_MODULE using SecureSettings().
    This wraps a settings module so that SECRET_KEY cannot be set within the
    given settings module.

    Use this function wherever you initialize Django, such as manage.py, wsgi
    modules, etc.
    """
    if conf.settings.configured:
        return

    settings_mod = os.environ.get(conf.ENVIRONMENT_VARIABLE)
    if not settings_mod:
        msg = "You must define the environment variable %s"
        raise conf.ImproperlyConfigured(msg % conf.ENVIRONMENT_VARIABLE)

    settings = SecureSettings(settings_mod)
    conf.settings.configure(settings)<commit_msg>added note about using secretkey w/o stored signatures<commit_after>import os

from django import conf
from django.utils.encoding import python_2_unicode_compatible

from secretkey import errors


class SecureSettings(conf.Settings):
    """
    Wraps a settings module so that SECRET_KEY cannot be set within the given
    settings module. Use this when configuring settings manually, otherwise use
    secretkey.settings.configure() in your manage.py and wsgi modules.

    The SECRET_KEY setting is loaded lazily in this class so that checks can be
    performed on the file first.
    """
    def __init__(self, settings_module):
        super(SecureSettings, self).__init__(settings_module)
        if not self.SECRET_KEY_FILE:
            raise conf.ImproperlyConfigured(
                "The SECRET_KEY_FILE setting must not be empty")

    def get_secret_key(self):
        try:
            with open(self.SECRET_KEY_FILE) as secret_key_file:
                return secret_key_file.read()
        except IOError as e:
            raise errors.SecretKeyFileNotFound(e)

    def _get_secret_key(self):
        # The super.__init__ method requires that SECRET_KEY is set, so give
        # it an object that will evaulate True when evaulated boolean-wise but
        # still cannot be evaulated as a string.
        if not conf.settings.configured:
            return UnusableSecretKey()
        if not hasattr(self, '_secret_key'):
            self._secret_key = self.get_secret_key()
        return self._secret_key

    def _set_secret_key(self, value):
        if not conf.settings.configured:
            return
        raise ValueError("The SECRET_KEY setting is read-only")

    def configure(self, **options):
        for name, value in options.iteritems():
            setattr(self, name, value)
        # Unfortunately LazySettings has no public API for extending the base
        # Settings class, so we have to override _wrapped here instead of
        # calling configure()
        conf.settings._wrapped = self

    SECRET_KEY = property(_get_secret_key, _set_secret_key)


@python_2_unicode_compatible
class UnusableSecretKey(object):
    def __str__(self):
        err = "SECRET_KEY cannot be used before settings are configured."
        raise ValueError(err)


def configure_secure():
    """
    Configures settings from DJANGO_SETTINGS_MODULE using SecureSettings().
    This wraps a settings module so that SECRET_KEY cannot be set within the
    given settings module.

    Use this function wherever you initialize Django, such as manage.py, wsgi
    modules, etc. If you want to enforce a file-based SECRET_KEY but do not
    wish to use the signature checking feature of django-secretkey, you can
    still use this function to configure your settings without having
    "secretkey" in your INSTALLED_APPS
    """
    if conf.settings.configured:
        return

    settings_mod = os.environ.get(conf.ENVIRONMENT_VARIABLE)
    if not settings_mod:
        msg = "You must define the environment variable %s"
        raise conf.ImproperlyConfigured(msg % conf.ENVIRONMENT_VARIABLE)

    settings = SecureSettings(settings_mod)
    conf.settings.configure(settings)
{'fraction_non_alphanumeric': 0.05996068152031455, 'fraction_numerical': 0.000655307994757536, 'mean_word_length': 2.9668615984405458, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3355388', 'n_tokens_mistral': 1697, 'n_tokens_neox': 1651, 'n_words': 584}