class Base(Configuration): DEBUG = values.BooleanValue(True) TEMPLATE_DEBUG = values.BooleanValue(DEBUG) DATABASES = values.DatabaseURLValue('sqlite:///dev.db') CONN_MAX_AGE = None INSTALLED_APPS = values.ListValue([ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', 'django.contrib.comments', 'django.contrib.sitemaps', # external 'south', 'haystack', 'djcelery', 'taggit', 'floppyforms', 'overextends', 'tastypie', 'tastypie_swagger', 'storages', 'compressor', # local 'froide.foirequest', 'froide.foirequestfollower', 'froide.frontpage', 'froide.publicbody', 'froide.account', 'froide.redaction', 'froide.foisite', 'froide.helper', ]) CACHES = values.CacheURLValue('dummy://') # ############# Site Configuration ######### # Make this unique, and don't share it with anybody. SECRET_KEY = 'make_me_unique!!' SITE_NAME = values.Value('Froide') SITE_EMAIL = values.Value('*****@*****.**') SITE_URL = values.Value('http://*****:*****@example.com'), ) MANAGERS = ADMINS INTERNAL_IPS = values.TupleValue(('127.0.0.1', )) # ############## PATHS ############### PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) LOCALE_PATHS = values.TupleValue( (os.path.abspath(os.path.join(PROJECT_ROOT, '..', "locale")), )) GEOIP_PATH = None # Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/home/media/media.lawrence.com/media/" MEDIA_ROOT = os.path.abspath(os.path.join(PROJECT_ROOT, "..", "files")) # Sub path in MEDIA_ROOT that will hold FOI attachments FOI_MEDIA_PATH = values.Value('foi') # Absolute path to the directory static files should be collected to. # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/home/media/media.lawrence.com/static/" STATIC_ROOT = os.path.abspath(os.path.join(PROJECT_ROOT, "..", "public")) # Additional locations of static files STATICFILES_DIRS = (os.path.join(PROJECT_ROOT, "static"), ) COMPRESS_ENABLED = values.BooleanValue(False) COMPRESS_JS_FILTERS = ['compressor.filters.jsmin.JSMinFilter'] COMPRESS_CSS_FILTERS = [ 'compressor.filters.css_default.CssAbsoluteFilter', 'compressor.filters.cssmin.CSSMinFilter' ] COMPRESS_PARSER = 'compressor.parser.HtmlParser' # Additional locations of template files TEMPLATE_DIRS = (os.path.join(PROJECT_ROOT, "templates"), ) # ########## URLs ################# ROOT_URLCONF = values.Value('froide.urls') # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash. # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" MEDIA_URL = values.Value('/files/') # URL prefix for static files. # Example: "http://media.lawrence.com/static/" # URL that handles the static files like app media. # Example: "http://media.lawrence.com" STATIC_URL = values.Value('/static/') USE_X_ACCEL_REDIRECT = values.BooleanValue(False) X_ACCEL_REDIRECT_PREFIX = values.Value('/protected') # ## URLs that can be translated to a secret value SECRET_URLS = values.DictValue({"admin": "admin"}) # ######## Backends, Finders, Processors, Classes #### AUTH_USER_MODEL = values.Value('account.User') CUSTOM_AUTH_USER_MODEL_DB = values.Value('') # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'django.contrib.staticfiles.finders.FileSystemFinder', 'compressor.finders.CompressorFinder', ) AUTHENTICATION_BACKENDS = [ "froide.helper.auth.EmailBackend", "django.contrib.auth.backends.ModelBackend", ] TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'froide.helper.context_processors.froide', 'froide.helper.context_processors.site_settings') # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ] MIDDLEWARE_CLASSES = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ] # ######### I18N and L10N ################## # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # On Unix systems, a value of None will cause Django to use the same # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = values.Value('Europe/Berlin') USE_TZ = values.BooleanValue(True) # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = values.Value('en-us') LANGUAGES = ( ('en', gettext('English')), ('fi-fi', gettext('Finnish (Finland)')), ('de', gettext('German')), ('it', gettext('Italian')), ('pt', gettext('Portuguese')), ('sv-se', gettext('Swedish (Sweden)')), ('sv-fi', gettext('Swedish (Finland)')), ('zh-cn', gettext('Chinese (Simplified)')), ('zh-hk', gettext('Chinese (Traditional, Hong Kong)')), ) # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = values.BooleanValue(True) # If you set this to False, Django will not format dates, numbers and # calendars according to the current locale USE_L10N = values.BooleanValue(True) DATE_FORMAT = values.Value("d. F Y") SHORT_DATE_FORMAT = values.Value("d.m.Y") DATE_INPUT_FORMATS = values.TupleValue(("%d.%m.%Y", )) SHORT_DATETIME_FORMAT = values.Value("d.m.Y H:i") DATETIME_INPUT_FORMATS = values.TupleValue(("%d.%m.%Y %H:%M", )) TIME_FORMAT = values.Value("H:i") TIME_INPUT_FORMATS = values.TupleValue(("%H:%M", )) HOLIDAYS = [ (1, 1), # New Year's Day (12, 25), # Christmas (12, 26) # Second day of Christmas ] # Weekends are non-working days HOLIDAYS_WEEKENDS = True # Calculates other holidays based on easter sunday HOLIDAYS_FOR_EASTER = (0, -2, 1, 39, 50, 60) # ######## Logging ########## # A sample logging configuration. LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'root': { 'level': 'WARNING', 'handlers': [], }, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' }, }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' }, 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', } }, 'loggers': { 'froide': { 'handlers': ['console'], 'propagate': True, 'level': 'DEBUG', }, 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, 'django.db.backends': { 'level': 'ERROR', 'handlers': ['console'], 'propagate': False, } } } # ######## Security ########### CSRF_COOKIE_SECURE = False CSRF_COOKIE_HTTPONLY = True CSRF_FAILURE_VIEW = values.Value('froide.account.views.csrf_failure') # Change this # ALLOWED_HOSTS = () SESSION_COOKIE_AGE = values.IntegerValue(3628800) # six weeks SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SECURE = False # ######## Celery ############# CELERY_RESULT_BACKEND = values.Value( 'djcelery.backends.database:DatabaseBackend') CELERYBEAT_SCHEDULER = values.Value( "djcelery.schedulers.DatabaseScheduler") CELERY_ALWAYS_EAGER = values.BooleanValue(True) CELERY_ROUTES = { 'froide.foirequest.tasks.fetch_mail': { "queue": "emailfetch" }, } # ######## Haystack ########### HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.simple_backend.SimpleEngine', } } # ######### Tastypie ######### TASTYPIE_SWAGGER_API_MODULE = values.Value('froide.urls.v1_api') # ######### Froide settings ######## FROIDE_THEME = None FROIDE_CONFIG = dict( create_new_publicbody=True, publicbody_empty=True, user_can_hide_web=True, public_body_officials_public=True, public_body_officials_email_public=False, request_public_after_due_days=14, payment_possible=True, currency="Euro", default_law=1, search_engine_query= "http://www.google.de/search?as_q=%(query)s&as_epq=&as_oq=&as_eq=&hl=en&lr=&cr=&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=%(domain)s&as_rights=&safe=images", greetings=[rec(u"Dear (?:Mr\.?|Ms\.? .*?)")], closings=[rec(u"Sincerely yours,?")], public_body_boosts={}, dryrun=False, dryrun_domain="testmail.example.com", allow_pseudonym=False, doc_conversion_binary=None, # replace with libreoffice instance doc_conversion_call_func=None, # see settings_test for use ) # ###### Email ############## # Django settings EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' EMAIL_SUBJECT_PREFIX = values.Value('[Froide] ') SERVER_EMAIL = values.Value('*****@*****.**') DEFAULT_FROM_EMAIL = values.Value('*****@*****.**') # Official Notification Mail goes through # the normal Django SMTP Backend EMAIL_HOST = values.Value("") EMAIL_PORT = values.IntegerValue(587) EMAIL_HOST_USER = values.Value("") EMAIL_HOST_PASSWORD = values.Value("") EMAIL_USE_TLS = values.BooleanValue(True) # Froide special case settings # IMAP settings for fetching mail FOI_EMAIL_PORT_IMAP = values.IntegerValue(993) FOI_EMAIL_HOST_IMAP = values.Value("imap.example.com") FOI_EMAIL_ACCOUNT_NAME = values.Value("*****@*****.**") FOI_EMAIL_ACCOUNT_PASSWORD = values.Value("") FOI_EMAIL_USE_SSL = values.BooleanValue(True) # SMTP settings for sending FoI mail FOI_EMAIL_HOST_USER = values.Value(FOI_EMAIL_ACCOUNT_NAME) FOI_EMAIL_HOST_FROM = values.Value(FOI_EMAIL_HOST_USER) FOI_EMAIL_HOST_PASSWORD = values.Value(FOI_EMAIL_ACCOUNT_PASSWORD) FOI_EMAIL_HOST = values.Value("smtp.example.com") FOI_EMAIL_PORT = values.IntegerValue(537) FOI_EMAIL_USE_TLS = values.BooleanValue(True) # The FoI Mail can use a different account FOI_EMAIL_DOMAIN = values.Value("example.com") FOI_EMAIL_TEMPLATE = None # Example: # FOI_EMAIL_TEMPLATE = lambda user_name, secret: "{username}.{secret}@{domain}" % (user_name, secret, FOI_EMAIL_DOMAIN) # Is the message you can send from fixed # or can you send from any address you like? FOI_EMAIL_FIXED_FROM_ADDRESS = values.BooleanValue(True) SOUTH_MIGRATION_MODULES = { 'taggit': 'taggit.south_migrations', }
class Base(Core, Elasticsearch): """Settings that may change per-environment, som defaults.""" # # Django SECRET_KEY = values.SecretValue() DEBUG = values.BooleanValue(default=False) ALLOWED_HOSTS = values.ListValue([]) _DATABASES = values.DatabaseURLValue("postgresql://localhost/buildhub2") CONN_MAX_AGE = values.IntegerValue(60) @property def DATABASES(self): """Because it's not possible to set 'CONN_MAX_AGE a URL, # we patch the 'DATABASES' dict *after* django-configurations has done its thing.""" DATABASES = self._DATABASES.value.copy() if self.CONN_MAX_AGE: DATABASES["default"]["CONN_MAX_AGE"] = self.CONN_MAX_AGE return DATABASES # Logging LOGGING_USE_JSON = values.BooleanValue(True) LOGGING_DEFAULT_LEVEL = values.Value("INFO") @property def LOGGING(self): return { "version": 1, "disable_existing_loggers": False, "formatters": { "json": { "()": "dockerflow.logging.JsonLogFormatter", "logger_name": "buildhub", }, "verbose": {"format": "%(levelname)s %(asctime)s %(name)s %(message)s"}, }, "handlers": { "console": { "level": self.LOGGING_DEFAULT_LEVEL, "class": "logging.StreamHandler", "formatter": ("json" if self.LOGGING_USE_JSON else "verbose"), }, "sentry": { "level": "ERROR", "class": ( "raven.contrib.django.raven_compat.handlers" ".SentryHandler" ), }, "null": {"class": "logging.NullHandler"}, }, "root": {"level": "INFO", "handlers": ["sentry", "console"]}, "loggers": { "django": { "level": "WARNING", "handlers": ["console"], "propagate": False, }, "django.db.backends": { "level": "ERROR", "handlers": ["console"], "propagate": False, }, "django.request": { "level": "INFO", "handlers": ["console"], "propagate": False, }, "raven": { "level": "DEBUG", "handlers": ["console"], "propagate": False, }, "sentry.errors": { "level": "DEBUG", "handlers": ["console"], "propagate": False, }, "buildhub": { "level": "DEBUG", "handlers": ["console"], "propagate": False, }, "backoff": { "level": "INFO", "handlers": ["console"], "propagate": False, }, "markus": { "level": "INFO", "handlers": ["console"], "propagate": False, }, "elasticsearch": { "level": "ERROR", "handlers": ["console"], "propagate": False, }, "request.summary": { "handlers": ["console"], "level": "INFO", "propagate": False, }, "django.security.DisallowedHost": { "handlers": ["null"], "propagate": False, }, }, }
class Common(Configuration): VERSION = '0.3.28' API_VERSION = 'v1.0.1' SITE_ID = 1 SECRET_KEY = get_secret_key() INSTALLED_APPS = [ 'django.contrib.sites', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'sortedm2m_filter_horizontal_widget', 'oidc_provider', 'rest_framework', 'rest_framework.authtoken', 'dj_rest_auth', 'dj_rest_auth.registration', 'multi_email_field', 'kubeportal', # positioned here to override allauth view templates 'allauth', 'allauth.account', 'allauth.socialaccount', 'allauth.socialaccount.providers.google', 'allauth.socialaccount.providers.oauth2', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'kubeportal.middleware.HideAdminForNonStaffMiddleware' ] ROOT_URLCONF = 'kubeportal.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django.template.context_processors.request', ], }, }, ] REST_FRAMEWORK = { 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', 'DEFAULT_AUTHENTICATION_CLASSES': [ 'dj_rest_auth.jwt_auth.JWTCookieAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_VERSION': API_VERSION, 'ALLOWED_VERSIONS': [ API_VERSION ] } REST_USE_JWT = True JWT_AUTH_COOKIE = 'kubeportal-auth' WSGI_APPLICATION = 'kubeportal.wsgi.application' AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', 'kubeportal.ad.ActiveDirectoryBackend', 'allauth.account.auth_backends.AuthenticationBackend' ) SOCIALACCOUNT_QUERY_EMAIL=True SOCIALACCOUNT_PROVIDERS = {} AUTH_AD_DOMAIN = values.Value(None, environ_prefix='KUBEPORTAL') AUTH_AD_SERVER = values.Value(None, environ_prefix='KUBEPORTAL') SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = values.Value( None, environ_name='AUTH_GOOGLE_KEY', environ_prefix='KUBEPORTAL') SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = values.Value( None, environ_name='AUTH_GOOGLE_SECRET', environ_prefix='KUBEPORTAL') if SOCIAL_AUTH_GOOGLE_OAUTH2_KEY and SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET: SOCIALACCOUNT_PROVIDERS['google'] = { 'APP': { 'secret': SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET, 'client_id': SOCIAL_AUTH_GOOGLE_OAUTH2_KEY }, 'SCOPE': ['profile', 'email'], } LOGIN_URL = '/' LOGIN_REDIRECT_URL = '/welcome/' LOGOUT_REDIRECT_URL = '/' STATIC_URL = '/static/' USE_I18N = True USE_L10N = True USE_TZ = True CORS_ORIGIN_ALLOW_ALL = True ALLOWED_HOSTS = ['*'] AUTH_USER_MODEL = 'kubeportal.User' OIDC_TEMPLATES = { 'authorize': 'oidc_authorize.html', 'error': 'oidc_error.html' } OIDC_IDTOKEN_INCLUDE_CLAIMS = True # include user email etc. in token SESSION_COOKIE_DOMAIN = values.Value(None, environ_prefix='KUBEPORTAL') NAMESPACE_CLUSTERROLES = values.ListValue([], environ_prefix='KUBEPORTAL') API_SERVER_EXTERNAL = values.Value(None, environ_prefix='KUBEPORTAL') BRANDING = values.Value('KubePortal', environ_prefix='KUBEPORTAL') LANGUAGE_CODE = values.Value('en-us', environ_prefix='KUBEPORTAL') TIME_ZONE = values.Value('UTC', environ_prefix='KUBEPORTAL') ADMIN_NAME = values.Value(environ_prefix='KUBEPORTAL') ADMIN_EMAIL = values.Value(environ_prefix='KUBEPORTAL') ADMINS = [(str(ADMIN_NAME), str(ADMIN_EMAIL)), ] OIDC_AFTER_USERLOGIN_HOOK = 'kubeportal.security.oidc_login_hook' ACCOUNT_ADAPTER = 'kubeportal.allauth.AccountAdapter'
class Base(Configuration): DEBUG = False SECRET_KEY = values.Value() ALLOWED_HOSTS = [] INSTALLED_APPS = [ # django apps "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", # third-party apps "rest_framework", "ckeditor", # project apps "buildings", "pages", ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] ROOT_URLCONF = "seismic_site.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] WSGI_APPLICATION = "seismic_site.wsgi.application" # Database # https://docs.djangoproject.com/en/2.2/ref/settings/#databases DATABASES = {"default": dj_database_url.config(conn_max_age=600)} # Password validation # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", # noqa }, { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", # noqa }, { "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", # noqa }, { "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", # noqa }, ] # Internationalization # https://docs.djangoproject.com/en/2.2/topics/i18n/ LANGUAGE_CODE = values.Value(default="en-us") TIME_ZONE = "UTC" USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.2/howto/static-files/ STATIC_URL = "/static/" STATIC_ROOT = os.path.join(BASE_DIR, "./public/static") # STATICFILES_DIRS = ( # os.path.join(BASE_DIR, 'static'), # ) STATICFILES_STORAGE = ( "whitenoise.storage.CompressedManifestStaticFilesStorage") MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, "./public/media") REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. "DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly"] }
class Common(Configuration): # APP CONFIGURATION DJANGO_APPS = ( # Default Django apps: 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # Useful template tags: # 'django.contrib.humanize', # Admin 'django.contrib.admin', ) THIRD_PARTY_APPS = ( 'crispy_forms', # Form layouts 'avatar', # for user avatars 'allauth', # registration 'allauth.account', # registration 'allauth.socialaccount', # registration ) # Apps specific for this project go here. LOCAL_APPS = ( 'users', # custom users app # Your stuff: custom apps go here ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS # END APP CONFIGURATION # MIDDLEWARE CONFIGURATION MIDDLEWARE_CLASSES = ( # Make sure djangosecure.middleware.SecurityMiddleware is listed first 'djangosecure.middleware.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) # END MIDDLEWARE CONFIGURATION # MIGRATIONS CONFIGURATION MIGRATION_MODULES = {'sites': 'contrib.sites.migrations'} # END MIGRATIONS CONFIGURATION # DEBUG # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = values.BooleanValue(False) # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug TEMPLATE_DEBUG = DEBUG # END DEBUG # SECRET CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key # Note: This key only used for development and testing. # In production, this is changed to a values.SecretValue() setting SECRET_KEY = "CHANGEME!!!" # END SECRET CONFIGURATION # FIXTURE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS FIXTURE_DIRS = (join(BASE_DIR, 'fixtures'), ) # END FIXTURE CONFIGURATION # EMAIL CONFIGURATION EMAIL_BACKEND = values.Value('django.core.mail.backends.smtp.EmailBackend') # END EMAIL CONFIGURATION # MANAGER CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#admins ADMINS = (("""{{cookiecutter.author_name}}""", '{{cookiecutter.email}}'), ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#managers MANAGERS = ADMINS # END MANAGER CONFIGURATION # DATABASE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = values.DatabaseURLValue( 'postgres://localhost/{{cookiecutter.repo_name}}') # END DATABASE CONFIGURATION # CACHING # Do this here because thanks to django-pylibmc-sasl and pylibmc # memcacheify (used on heroku) is painful to install on windows. CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': '' } } # END CACHING # GENERAL CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone TIME_ZONE = 'America/Los_Angeles' # See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code LANGUAGE_CODE = 'en-us' # See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id SITE_ID = 1 # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n USE_I18N = True # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n USE_L10N = True # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz USE_TZ = True # END GENERAL CONFIGURATION # TEMPLATE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors TEMPLATE_CONTEXT_PROCESSORS = ( 'django.contrib.auth.context_processors.auth', "allauth.account.context_processors.account", "allauth.socialaccount.context_processors.socialaccount", 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.tz', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.request', # Your stuff: custom template context processers go here ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs TEMPLATE_DIRS = (join(BASE_DIR, 'templates'), ) TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ) # See: http://django-crispy-forms.readthedocs.org/en/latest/install.html#template-packs CRISPY_TEMPLATE_PACK = 'bootstrap3' # END TEMPLATE CONFIGURATION # STATIC FILE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root STATIC_ROOT = join(os.path.dirname(BASE_DIR), 'staticfiles') # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url STATIC_URL = '/static/' # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS STATICFILES_DIRS = (join(BASE_DIR, 'static'), ) # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) # END STATIC FILE CONFIGURATION # MEDIA CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root MEDIA_ROOT = join(BASE_DIR, 'media') # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url MEDIA_URL = '/media/' # END MEDIA CONFIGURATION # URL Configuration ROOT_URLCONF = 'urls' # See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application WSGI_APPLICATION = 'wsgi.application' # End URL Configuration # AUTHENTICATION CONFIGURATION AUTHENTICATION_BACKENDS = ( "django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend", ) # Some really nice defaults ACCOUNT_AUTHENTICATION_METHOD = "username" ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_EMAIL_VERIFICATION = "mandatory" # END AUTHENTICATION CONFIGURATION # Custom user app defaults # Select the correct user model AUTH_USER_MODEL = "users.User" LOGIN_REDIRECT_URL = "users:redirect" LOGIN_URL = "account_login" # END Custom user app defaults # SLUGLIFIER AUTOSLUG_SLUGIFY_FUNCTION = "slugify.slugify" # END SLUGLIFIER # LOGGING CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#logging # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error when DEBUG=False. # See http://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' } }, 'loggers': { 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, } }
class Production(Common): # This ensures that Django will be able to detect a secure connection # properly on Heroku. SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') # INSTALLED_APPS INSTALLED_APPS = Common.INSTALLED_APPS # END INSTALLED_APPS # SECRET KEY SECRET_KEY = values.SecretValue() # END SECRET KEY # django-secure INSTALLED_APPS += ("djangosecure", ) # set this to 60 seconds and then to 518400 when you can prove it works SECURE_HSTS_SECONDS = 60 SECURE_HSTS_INCLUDE_SUBDOMAINS = values.BooleanValue(True) SECURE_FRAME_DENY = values.BooleanValue(True) SECURE_CONTENT_TYPE_NOSNIFF = values.BooleanValue(True) SECURE_BROWSER_XSS_FILTER = values.BooleanValue(True) SESSION_COOKIE_SECURE = values.BooleanValue(False) SESSION_COOKIE_HTTPONLY = values.BooleanValue(True) SECURE_SSL_REDIRECT = values.BooleanValue(True) # end django-secure # SITE CONFIGURATION # Hosts/domain names that are valid for this site # See https://docs.djangoproject.com/en/1.6/ref/settings/#allowed-hosts ALLOWED_HOSTS = ["*"] # END SITE CONFIGURATION INSTALLED_APPS += ("gunicorn", ) # STORAGE CONFIGURATION # See: http://django-storages.readthedocs.org/en/latest/index.html INSTALLED_APPS += ( 'storages', ) # See: http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html#settings STATICFILES_STORAGE = DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' # See: http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html#settings AWS_ACCESS_KEY_ID = values.SecretValue() AWS_SECRET_ACCESS_KEY = values.SecretValue() AWS_STORAGE_BUCKET_NAME = values.SecretValue() AWS_AUTO_CREATE_BUCKET = True AWS_QUERYSTRING_AUTH = False # see: https://github.com/antonagestam/collectfast AWS_PRELOAD_METADATA = True INSTALLED_APPS += ('collectfast', ) # AWS cache settings, don't change unless you know what you're doing: AWS_EXPIRY = 60 * 60 * 24 * 7 AWS_HEADERS = { 'Cache-Control': 'max-age=%d, s-maxage=%d, must-revalidate' % ( AWS_EXPIRY, AWS_EXPIRY) } # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url STATIC_URL = 'https://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME # END STORAGE CONFIGURATION # EMAIL DEFAULT_FROM_EMAIL = values.Value('bookmap <*****@*****.**>') EMAIL_HOST = values.Value('smtp.sendgrid.com') EMAIL_HOST_PASSWORD = values.SecretValue(environ_prefix="", environ_name="SENDGRID_PASSWORD") EMAIL_HOST_USER = values.SecretValue(environ_prefix="", environ_name="SENDGRID_USERNAME") EMAIL_PORT = values.IntegerValue(587, environ_prefix="", environ_name="EMAIL_PORT") EMAIL_SUBJECT_PREFIX = values.Value('[bookmap] ', environ_name="EMAIL_SUBJECT_PREFIX") EMAIL_USE_TLS = True SERVER_EMAIL = EMAIL_HOST_USER # END EMAIL # TEMPLATE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs TEMPLATE_LOADERS = ( ('django.template.loaders.cached.Loader', ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', )), ) # END TEMPLATE CONFIGURATION # CACHING # Only do this here because thanks to django-pylibmc-sasl and pylibmc # memcacheify is painful to install on windows. try: # See: https://github.com/rdegges/django-heroku-memcacheify from memcacheify import memcacheify CACHES = memcacheify() except ImportError: CACHES = values.CacheURLValue(default="memcached://127.0.0.1:11211")
class Common(Configuration): '''Common Configuration, overide them in it's sub-classes.''' # APP CONFIGURATION # ----------------- DJANGO_APPS = ( # Default Django apps: 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # Useful template tags: # 'django.contrib.humanize', # Admin 'django.contrib.admin', ) THIRD_PARTY_APPS = ( 'south', # Database migration helpers 'django_extensions', # http://django-extensions.readthedocs.org/ ) LOCAL_APPS = ( # Your stuff: custom apps go here 'pages', ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS # MIDDLEWARE CONFIGURATION # Note: Order in which they are added are important MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) # END MIDDLEWARE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug # Defaults to false, which is safe, enable them only in development. DEBUG = values.BooleanValue(False) # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug TEMPLATE_DEBUG = DEBUG # SECRET CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key # Note: This key only used for development and testing. # In production, this is changed to a values.SecretValue() setting SECRET_KEY = "CHANGEME_TO_SOME_S3CRET_VALUE!!!" # END SECRET CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS FIXTURE_DIRS = (join(BASE_DIR, 'fixtures'), ) # MANAGER CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#admins ADMINS = (('Vault admin', '*****@*****.**'), ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#managers MANAGERS = ADMINS # END MANAGER CONFIGURATION # EMAIL CONFIGURATION EMAIL_BACKEND = values.Value('django.core.mail.backends.smtp.EmailBackend') # END EMAIL CONFIGURATION # DATABASE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = values.DatabaseURLValue( 'postgres://vault-backend@localhost/vault-backend') # END DATABASE CONFIGURATION SITE_ID = 1 # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # In a Windows environment this must be set to your system time zone. TIME_ZONE = 'UTC' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-us' # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # If you set this to False, Django will not format dates, numbers and # calendars according to the current locale. USE_L10N = True # If you set this to False, Django will not use timezone-aware datetimes. USE_TZ = True # TEMPLATE CONFIGURATION TEMPLATE_CONTEXT_PROCESSORS = ( 'django.contrib.auth.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.tz', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.request', # Your stuff: custom template context processers go here ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs TEMPLATE_DIRS = (join(BASE_DIR, 'templates'), ) # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ) # STATIC FILE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root STATIC_ROOT = join(os.path.dirname(BASE_DIR), 'staticfiles') # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url STATIC_URL = '/static/' # See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS STATICFILES_DIRS = (join(BASE_DIR, 'static'), ) # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) # END STATIC FILE CONFIGURATION # MEDIA CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root MEDIA_ROOT = join(BASE_DIR, 'media') # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url MEDIA_URL = '/media/' # END MEDIA CONFIGURATION # URL Configuration ROOT_URLCONF = 'urls' # See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application WSGI_APPLICATION = 'wsgi.application' # End URL Configuration # AUTHENTICATION CONFIGURATION AUTHENTICATION_BACKENDS = ("django.contrib.auth.backends.ModelBackend", ) # SLUGLIFIER AUTOSLUG_SLUGIFY_FUNCTION = "slugify.slugify" # END SLUGLIFIER # LOGGING CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#logging # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error when DEBUG=False. # See http://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' } }, 'loggers': { 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, } }
class Common(Configuration): # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '5w$77!lmo&g)e5j6uhl4i2=nffnnj0y1y07(9@-f)@b7*g%+sd' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] INTERNAL_IPS = [ '127.0.0.1', ] # Application definition INSTALLED_APPS = [ 'core.apps.CoreConfig', 'heating.apps.HeatingConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_filters', 'rest_framework', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'home_web.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'home_web.wsgi.application' # Database # https://docs.djangoproject.com/en/1.10/ref/settings/#databases DATABASES = values.DatabaseURLValue( 'sqlite:///{}'.format(os.path.join(BASE_DIR, 'db.sqlite3')) ) # Password validation # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.' 'UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.' 'MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.' 'CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.' 'NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.10/topics/i18n/ LANGUAGE_CODE = 'fr-FR' TIME_ZONE = 'Europe/Paris' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.10/howto/static-files/ STATIC_URL = '/static/' REDIS_URL = values.Value() CELERY_BROKER_URL = CeleryBrokerURLValue(environ_name='REDIS_URL') CELERY_TASK_ROUTES = { 'heating.tasks.*': {'queue': 'celery', 'delivery_mode': 'transient'}, } CELERY_BEAT_SCHEDULE = { 'update-pilotwire-status': { 'task': 'heating.pilotwire.update_status', 'schedule': 60, }, 'set-pilotwire-modes': { 'task': 'heating.pilotwire.set_modes', 'schedule': crontab(minute='*/15'), }, 'weekly-clear-old-derogations': { 'task': 'heating.tasks.clearoldderogations', 'schedule': crontab(minute=0, hour=0, day_of_week='mon'), 'args': (7,), }, } CELERY_TIME_ZONE = TIME_ZONE PILOTWIRE_IP = values.IPValue() PILOTWIRE_PORT = values.IntegerValue()
class Base(Configuration): DEBUG = values.BooleanValue(True) CONN_MAX_AGE = None INSTALLED_APPS = values.ListValue([ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', 'django_comments', 'django.contrib.flatpages', 'django.contrib.sitemaps', 'django.contrib.humanize', 'django.contrib.gis', 'channels', # overwrite management command in # django_elasticsearch_dsl 'froide.helper', # external 'django_elasticsearch_dsl', 'taggit', 'storages', 'treebeard', 'django_filters', 'leaflet', 'django_celery_beat', # Semi-external 'filingcabinet', # local 'froide.foirequest', 'froide.foirequestfollower', 'froide.frontpage', 'froide.georegion', 'froide.publicbody', 'froide.document', 'froide.letter', 'froide.account', 'froide.bounce', 'froide.team', 'froide.foisite', 'froide.problem', 'froide.accesstoken', 'froide.guide', 'froide.comments', 'froide.campaign', 'froide.upload', # API 'oauth2_provider', 'rest_framework', ]) DATABASES = values.DatabaseURLValue('postgis://*****:*****@localhost:5432/froide') CACHES = values.CacheURLValue('dummy://') CHANNEL_LAYERS = { "default": { "BACKEND": "channels.layers.InMemoryChannelLayer" } } # ############# Site Configuration ######### # Make this unique, and don't share it with anybody. SECRET_KEY = 'make_me_unique!!' SITE_NAME = values.Value('Froide') SITE_EMAIL = values.Value('*****@*****.**') SITE_URL = values.Value('http://*****:*****@example.com'), ) MANAGERS = ADMINS INTERNAL_IPS = values.TupleValue(('127.0.0.1',)) # ############## PATHS ############### PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) LOCALE_PATHS = values.TupleValue( (os.path.abspath(os.path.join(PROJECT_ROOT, '..', "locale")),) ) GEOIP_PATH = None # Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/home/media/media.lawrence.com/media/" MEDIA_ROOT = values.Value(os.path.abspath(os.path.join(PROJECT_ROOT, "..", "files"))) # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash. # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" MEDIA_URL = values.Value('/files/') # Sub path in MEDIA_ROOT that will hold FOI attachments FOI_MEDIA_PATH = values.Value('foi') FOI_MEDIA_TOKEN_EXPIRY = 2 * 60 INTERNAL_MEDIA_PREFIX = values.Value('/protected/') # Absolute path to the directory static files should be collected to. # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/home/media/media.lawrence.com/static/" STATIC_ROOT = values.Value(os.path.abspath(os.path.join(PROJECT_ROOT, "..", "public"))) # Additional locations of static files STATICFILES_DIRS = ( os.path.join(PROJECT_ROOT, "static"), ) # ########## URLs ################# ROOT_URLCONF = values.Value('froide.urls') ASGI_APPLICATION = "froide.routing.application" # URL prefix for static files. # Example: "http://media.lawrence.com/static/" # URL that handles the static files like app media. # Example: "http://media.lawrence.com" STATIC_URL = values.Value('/static/') # ## URLs that can be translated to a secret value SECRET_URLS = values.DictValue({ "admin": "admin" }) # ######## Backends, Finders, Processors, Classes #### AUTH_USER_MODEL = values.Value('account.User') AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', 'froide.foirequest.auth_backend.FoiRequestAuthBackend' ] PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 'froide.account.hashers.PBKDF2WrappedSHA1PasswordHasher', ] MIN_PASSWORD_LENGTH = 9 AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 'OPTIONS': { 'min_length': MIN_PASSWORD_LENGTH, } }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'django.contrib.staticfiles.finders.FileSystemFinder', ) TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(PROJECT_ROOT, "templates"), ], 'OPTIONS': { 'debug': values.BooleanValue(DEBUG), 'loaders': [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ], 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'froide.helper.context_processors.froide', 'froide.helper.context_processors.site_settings', 'froide.helper.context_processors.block_helper' ] } } ] MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'oauth2_provider.middleware.OAuth2TokenMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] X_FRAME_OPTIONS = 'SAMEORIGIN' COMMENTS_APP = 'froide.comments' # ######### I18N and L10N ################## # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # On Unix systems, a value of None will cause Django to use the same # timezone as the operating system. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = values.Value('Europe/Berlin') USE_TZ = values.BooleanValue(True) # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = values.Value('en') LANGUAGES = ( ('en', _('English')), ('es', _('Spanish')), ('fi-fi', _('Finnish (Finland)')), ('de', _('German')), ('da-dk', _('Danish (Denmark)')), ('it', _('Italian')), ('pt', _('Portuguese')), ('sv-se', _('Swedish (Sweden)')), ('sv-fi', _('Swedish (Finland)')), ('zh-cn', _('Chinese (Simplified)')), ('zh-hk', _('Chinese (Traditional, Hong Kong)')), ) # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = values.BooleanValue(True) # If you set this to False, Django will not format dates, numbers and # calendars according to the current locale USE_L10N = values.BooleanValue(True) DATE_FORMAT = values.Value("d. F Y") SHORT_DATE_FORMAT = values.Value("d.m.Y") DATE_INPUT_FORMATS = values.TupleValue(("%d.%m.%Y",)) SHORT_DATETIME_FORMAT = values.Value("d.m.Y H:i") DATETIME_INPUT_FORMATS = values.TupleValue(("%d.%m.%Y %H:%M",)) TIME_FORMAT = values.Value("H:i") TIME_INPUT_FORMATS = values.TupleValue(("%H:%M",)) TAGGIT_CASE_INSENSITIVE = True HOLIDAYS = [ (1, 1), # New Year's Day (12, 25), # Christmas (12, 26) # Second day of Christmas ] # Weekends are non-working days HOLIDAYS_WEEKENDS = True # Calculates other holidays based on easter sunday HOLIDAYS_FOR_EASTER = (0, -2, 1, 39, 50, 60) # ######## Logging ########## # A sample logging configuration. LOGGING = { 'version': 1, 'disable_existing_loggers': True, 'root': { 'level': 'WARNING', 'handlers': [], }, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' }, }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' }, 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', } }, 'loggers': { 'froide': { 'handlers': ['console'], 'propagate': True, 'level': 'DEBUG', }, 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, 'django.db.backends': { 'level': 'ERROR', 'handlers': ['console'], 'propagate': False, } } } # ######## Security ########### CSRF_COOKIE_SECURE = False CSRF_FAILURE_VIEW = values.Value('froide.account.views.csrf_failure') # Change this # ALLOWED_HOSTS = () ALLOWED_REDIRECT_HOSTS = () SESSION_COOKIE_AGE = values.IntegerValue(3628800) # six weeks SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SECURE = False CSRF_COOKIE_SAMESITE = None SESSION_COOKIE_SAMESITE = None # ######## FilingCabinet Document #### # FILINGCABINET_DOCUMENT_MODEL = 'document.Document' # FILINGCABINET_DOCUMENTCOLLECTION_MODEL = 'document.DocumentCollection' FILINGCABINET_DOCUMENT_MODEL = 'document.Document' FILINGCABINET_DOCUMENTCOLLECTION_MODEL = 'document.DocumentCollection' FILINGCABINET_MEDIA_PUBLIC_PREFIX = 'docs' FILINGCABINET_MEDIA_PRIVATE_PREFIX = 'docs-private' # ######## Celery ############# CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' # Attention: The following schedule will be synchronized to the database CELERY_BEAT_SCHEDULE = { 'fetch-mail': { 'task': 'froide.foirequest.tasks.fetch_mail', 'schedule': crontab(), }, 'detect-asleep': { 'task': 'froide.foirequest.tasks.detect_asleep', 'schedule': crontab(hour=0, minute=0), }, 'detect-overdue': { 'task': 'froide.foirequest.tasks.detect_overdue', 'schedule': crontab(hour=0, minute=0), }, 'update-foirequestfollowers': { 'task': 'froide.foirequestfollower.tasks.batch_update', 'schedule': crontab(hour=0, minute=0), }, 'classification-reminder': { 'task': 'froide.foirequest.tasks.classification_reminder', 'schedule': crontab(hour=7, minute=0, day_of_week=6), }, 'bounce-checker': { 'task': 'froide.bounce.tasks.check_bounces', 'schedule': crontab(hour=3, minute=0), }, 'account-maintenance': { 'task': 'froide.account.tasks.account_maintenance_task', 'schedule': crontab(hour=4, minute=0) }, 'upload-maintenance': { 'task': 'froide.upload.tasks.remove_expired_uploads', 'schedule': crontab(hour=3, minute=30) } } CELERY_TASK_ALWAYS_EAGER = values.BooleanValue(True) CELERY_TASK_ROUTES = { 'froide.foirequest.tasks.fetch_mail': {"queue": "emailfetch"}, 'froide.foirequest.tasks.process_mail': {"queue": "email"}, 'djcelery_email_send_multiple': {"queue": "emailsend"}, 'froide.helper.tasks.*': {"queue": "searchindex"}, 'froide.foirequest.tasks.redact_attachment_task': {"queue": "redact"}, 'froide.foirequest.tasks.ocr_pdf_task': {"queue": "ocr"}, 'filingcabinet.tasks.*': {"queue": "document"}, 'froide.foirequest.tasks.convert_images_to_pdf_task': {"queue": "convert"}, 'froide.foirequest.tasks.convert_attachment_task': {"queue": "convert_office"}, } CELERY_TIMEZONE = 'UTC' # We need to serialize email data as binary # which doesn't work well in JSON CELERY_TASK_SERIALIZER = 'pickle' CELERY_RESULT_SERIALIZER = 'pickle' CELERY_ACCEPT_CONTENT = ['pickle'] CELERY_EMAIL_TASK_CONFIG = { 'queue': 'emailsend' } EMAIL_BULK_QUEUE = 'emailsend_bulk' # ######## Search ########### ELASTICSEARCH_INDEX_PREFIX = 'froide' ELASTICSEARCH_HOST = values.Value('localhost') ELASTICSEARCH_DSL = { 'default': { 'hosts': '%s:9200' % ELASTICSEARCH_HOST }, } ELASTICSEARCH_DSL_SIGNAL_PROCESSOR = 'django_elasticsearch_dsl.signals.RealTimeSignalProcessor' # ######### API ######### # Do not include xml by default, so lxml doesn't need to be present TASTYPIE_DEFAULT_FORMATS = ['json'] OAUTH2_PROVIDER = { 'SCOPES': { 'read:user': _('Access to user status'), 'read:profile': _('Read user profile information'), 'read:email': _('Read user email'), 'read:request': _('Read your (private) requests'), 'make:request': _('Make requests on your behalf'), 'follow:request': _('Follow/Unfollow requests'), 'read:document': _('Read your (private) documents'), } } OAUTH2_PROVIDER_APPLICATION_MODEL = 'account.Application' LOGIN_URL = 'account-login' REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', 'rest_framework.authentication.SessionAuthentication', ), 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticatedOrReadOnly', ), 'DEFAULT_PAGINATION_CLASS': 'froide.helper.api_utils.CustomLimitOffsetPagination', 'PAGE_SIZE': 50, 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',), 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'froide.helper.api_renderers.CustomPaginatedCSVRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ) } # ######### Froide settings ######## FROIDE_CONFIG = dict( spam_protection=True, user_can_hide_web=True, public_body_officials_public=True, public_body_officials_email_public=False, request_public_after_due_days=14, payment_possible=True, currency="Euro", default_law=1, search_engine_query="http://www.google.de/search?as_q=%(query)s&as_epq=&as_oq=&as_eq=&hl=en&lr=&cr=&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=%(domain)s&as_rights=&safe=images", greetings=[rec(r"Dear (?:Mr\.?|Mr?s\.? .*?)")], redact_salutation=r"(?:Mr\.?|Mr?s\.?)", custom_replacements=[], closings=[rec(r"Sincerely yours,?")], public_body_boosts={}, autocomplete_body_boosts={}, read_receipt=False, delivery_receipt=False, dsn=False, target_countries=None, delivery_reporter=None, request_throttle=None, # Set to [(15, 7 * 24 * 60 * 60),] for 15 requests in 7 days message_throttle=[ (2, 5 * 60), # X messages in X seconds (6, 6 * 60 * 60), (8, 24 * 60 * 60), ], allow_pseudonym=False, doc_conversion_binary=None, # replace with libreoffice instance doc_conversion_call_func=None, # see settings_test for use content_urls={ 'terms': '/terms/', 'privary': '/privacy/', 'about': '/about/', 'help': '/help/', }, message_handlers={ 'email': 'froide.foirequest.message_handlers.EmailMessageHandler' }, recipient_blocklist_regex=None, max_attachment_size=1024 * 1024 * 10, # 10 MB bounce_enabled=False, bounce_max_age=60 * 60 * 24 * 14, # 14 days bounce_format='bounce+{token}@example.com', unsubscribe_enabled=False, unsubscribe_format='unsub+{token}@example.com', auto_reply_subject_regex=rec('^(Auto-?Reply|Out of office)'), auto_reply_email_regex=rec('^auto(reply|responder)@'), hide_content_funcs=[] ) TESSERACT_DATA_PATH = values.Value('/usr/local/share/tessdata') # ###### Email ############## # Django settings EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' EMAIL_SUBJECT_PREFIX = values.Value('[Froide] ') SERVER_EMAIL = values.Value('*****@*****.**') DEFAULT_FROM_EMAIL = values.Value('*****@*****.**') # Official Notification Mail goes through # the normal Django SMTP Backend EMAIL_HOST = values.Value("") EMAIL_PORT = values.IntegerValue(587) EMAIL_HOST_USER = values.Value("") EMAIL_HOST_PASSWORD = values.Value("") EMAIL_USE_TLS = values.BooleanValue(True) # Froide special case settings # IMAP settings for fetching mail FOI_EMAIL_PORT_IMAP = values.IntegerValue(993) FOI_EMAIL_HOST_IMAP = values.Value("imap.example.com") FOI_EMAIL_ACCOUNT_NAME = values.Value("*****@*****.**") FOI_EMAIL_ACCOUNT_PASSWORD = values.Value("") FOI_EMAIL_USE_SSL = values.BooleanValue(True) # SMTP settings for sending FoI mail FOI_EMAIL_HOST_USER = values.Value(FOI_EMAIL_ACCOUNT_NAME) FOI_EMAIL_HOST_FROM = values.Value(FOI_EMAIL_HOST_USER) FOI_EMAIL_HOST_PASSWORD = values.Value(FOI_EMAIL_ACCOUNT_PASSWORD) FOI_EMAIL_HOST = values.Value("smtp.example.com") FOI_EMAIL_PORT = values.IntegerValue(587) FOI_EMAIL_USE_TLS = values.BooleanValue(True) # The FoI Mail can use a different account FOI_EMAIL_DOMAIN = values.Value("example.com") FOI_EMAIL_TEMPLATE = None # Example: # FOI_EMAIL_TEMPLATE = lambda user_name, secret: "{username}.{secret}@{domain}" % (user_name, secret, FOI_EMAIL_DOMAIN) # Is the message you can send from fixed # or can you send from any address you like? FOI_EMAIL_FIXED_FROM_ADDRESS = values.BooleanValue(True) BOUNCE_EMAIL_HOST_IMAP = values.Value('') BOUNCE_EMAIL_PORT_IMAP = values.Value(143) BOUNCE_EMAIL_ACCOUNT_NAME = values.Value('') BOUNCE_EMAIL_ACCOUNT_PASSWORD = values.Value('') BOUNCE_EMAIL_USE_SSL = values.Value(False) UNSUBSCRIBE_EMAIL_HOST_IMAP = values.Value('') UNSUBSCRIBE_EMAIL_PORT_IMAP = values.Value(143) UNSUBSCRIBE_EMAIL_ACCOUNT_NAME = values.Value('') UNSUBSCRIBE_EMAIL_ACCOUNT_PASSWORD = values.Value('') UNSUBSCRIBE_EMAIL_USE_SSL = values.Value(False)
class Common(Configuration): INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Third party apps 'rest_framework', # utilities for rest apis 'rest_framework.authtoken', # token authentication 'django_rq', # asynchronous queuing 'versatileimagefield', # image manipulation # Your apps 'authentication', 'users') # https://docs.djangoproject.com/en/1.8/topics/http/middleware/ MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware') ROOT_URLCONF = 'urls' SECRET_KEY = 'Not a secret' WSGI_APPLICATION = 'wsgi.application' # Email EMAIL_BACKEND = values.Value('django.core.mail.backends.smtp.EmailBackend') MANAGERS = (('Author', '{{cookiecutter.email}}'), ) # Postgres DATABASES = values.DatabaseURLValue( 'postgres://localhost/{{cookiecutter.app_name}}') # General APPEND_SLASH = values.BooleanValue(False) TIME_ZONE = 'UTC' LANGUAGE_CODE = 'en-us' # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = False USE_L10N = True USE_TZ = True LOGIN_REDIRECT_URL = '/' # Static Files STATIC_ROOT = join(os.path.dirname(BASE_DIR), 'staticfiles') STATICFILES_DIRS = [ join(os.path.dirname(BASE_DIR), 'static'), ] STATIC_URL = '/static/' STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) # Media files MEDIA_ROOT = join(os.path.dirname(BASE_DIR), 'media') MEDIA_URL = '/media/' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [STATICFILES_DIRS], 'OPTIONS': { 'context_processors': [ 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.debug', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.tz', 'django.contrib.messages.context_processors.messages' ], 'loaders': [ ('django.template.loaders.cached.Loader', [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ]), ], }, }, ] # Set DEBUG to False as a default for safety # https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = values.BooleanValue(False) for config in TEMPLATES: config['OPTIONS']['debug'] = DEBUG # Logging LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' }, 'simple': { 'format': '%(levelname)s %(message)s' }, 'rq_console': { 'format': '%(asctime)s %(message)s', 'datefmt': '%H:%M:%S', }, }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' }, 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'rq_console': { 'level': 'DEBUG', 'class': 'rq.utils.ColorizingStreamHandler', 'formatter': 'rq_console', 'exclude': ['%(asctime)s'], }, }, 'loggers': { 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True }, 'rq.worker': { 'handlers': ['rq_console'], 'level': 'DEBUG' }, } } # Custom user app AUTH_USER_MODEL = 'users.User' # Django Rest Framework REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 100, 'DATETIME_FORMAT': '%Y-%m-%dT%H:%M:%S%z', 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ), 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', ) } # Versatile Image Field VERSATILEIMAGEFIELD_SETTINGS = { # The amount of time, in seconds, that references to created images # should be stored in the cache. Defaults to `2592000` (30 days) 'cache_length': 2592000, 'cache_name': 'versatileimagefield_cache', 'jpeg_resize_quality': 70, 'sized_directory_name': '__sized__', 'filtered_directory_name': '__filtered__', 'placeholder_directory_name': '__placeholder__', 'create_images_on_demand': False }
class Common(Configuration): ADMINS = (('Admin', '*****@*****.**'), ) # You'll likely want to add your own auth model. AUTH_USER_MODEL = 'custom_user.EmailUser' MANAGERS = ADMINS # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(__file__)) sys.path.insert(0, os.path.join(BASE_DIR, 'outline/apps')) USE_SOUTH = False # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False # Application definition INSTALLED_APPS = ( "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.redirects", "django.contrib.sessions", "django.contrib.sites", "django.contrib.sitemaps", "django.contrib.staticfiles", 'custom_user', 'allauth', 'allauth.account', 'allauth.socialaccount', 'allauth.socialaccount.providers.github', 'allauth.socialaccount.providers.google', "django_extensions", 'floppyforms', 'rest_framework', ) TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, "outline/templates")], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this # list if you haven't customized them: 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.debug', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.request', 'django.template.context_processors.tz', 'django.contrib.messages.context_processors.messages', ], }, }, ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'debug_toolbar.middleware.DebugToolbarMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] STATICFILES_FINDERS = ( "django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.AppDirectoriesFinder", ) ACCOUNT_AUTHENTICATION_METHOD = "email" ACCOUNT_USER_MODEL_USERNAME_FIELD = None ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_UNIQUE_EMAIL = True ACCOUNT_USERNAME_REQUIRED = False AUTHENTICATION_BACKENDS = ( "django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend", ) ROOT_URLCONF = 'outline.urls' WSGI_APPLICATION = 'outline.wsgi.application' DATABASES = values.DatabaseURLValue('sqlite:///{0}'.format(os.path.join( BASE_DIR, 'db.sqlite3'), environ=True)) NEVERCACHE_KEY = values.Value('klladsf-wefkjlwef-wekjlwef--wefjlkjfslkxvl') #CACHES = values.CacheURLValue('memcached://127.0.0.1:11211') # Internationalization # https://docs.djangoproject.com/en/1.6/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'America/New_York' USE_I18N = True USE_L10N = True USE_TZ = True SITE_ID = 1 ALLOWED_HOSTS = values.Value('*') SESSION_EXPIRE_AT_BROWSER_CLOSE = True PROJECT_DIRNAME = BASE_DIR.split(os.sep)[-1] CACHE_MIDDLEWARE_KEY_PREFIX = PROJECT_DIRNAME MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, 'public/media') STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'public/static') STATICFILES_DIRS = (os.path.join(BASE_DIR, "outline/static"), ) #DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' AWS_ACCESS_KEY_ID = values.Value() AWS_SECRET_ACCESS_KEY = values.Value() AWS_STORAGE_BUCKET_NAME = 'example.com' AWS_HEADERS = { 'ExpiresDefault': 'access plus 30 days', 'Cache-Control': 'max-age=86400', } # Account activations automatically expire after this period ACCOUNT_ACTIVATION_DAYS = 14 LOGIN_EXEMPT_URLS = [ '', '/', '/accounts/login/', 'login', '/accounts/signup/' ] LOGIN_URL = '/accounts/login/' LOGIN_REDIRECT_URL = '/' LOGOUT_URL = '/accounts/logout/' # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error when DEBUG=False. # See http://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler' } }, 'loggers': { 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, } }
class Common(Configuration): # APP CONFIGURATION DJANGO_APPS = ( # Default Django apps: 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', # redirects app 'django.contrib.redirects', # Useful template tags: # 'django.contrib.humanize', # Admin 'suitlocale', 'suit', 'django.contrib.admin', ) THIRD_PARTY_APPS = ( 'crispy_forms', 'allauth', # 'allauth.account', 'sorl.thumbnail', 'envelope', 'solo', 'django_perseus', 'rest_framework', 'ckeditor', 'widget_tweaks', 'wkhtmltopdf', 'taggit' ) # Apps specific for this project go here. LOCAL_APPS = ( 'pdf_kit', 'cacao', 'configuracion', ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS # END APP CONFIGURATION # MIDDLEWARE CONFIGURATION MIDDLEWARE_CLASSES = ( # Make sure djangosecure.middleware.SecurityMiddleware is listed first # 'djangosecure.middleware.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # redirect middleware 'django.contrib.redirects.middleware.RedirectFallbackMiddleware', ) # END MIDDLEWARE CONFIGURATION # MIGRATIONS CONFIGURATION MIGRATION_MODULES = { 'sites': 'contrib.sites.migrations' } # END MIGRATIONS CONFIGURATION # DEBUG # See: https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = values.BooleanValue(False) # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug TEMPLATE_DEBUG = DEBUG # END DEBUG # SECRET CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key # Note: This key only used for development and testing. # In production, this is changed to a values.SecretValue() setting SECRET_KEY = "CHANGEME!!!" # END SECRET CONFIGURATION # FIXTURE CONFIGURATION # See: # https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS FIXTURE_DIRS = ( join(BASE_DIR, 'fixtures'), ) # END FIXTURE CONFIGURATION # EMAIL CONFIGURATION EMAIL_BACKEND = values.Value('django.core.mail.backends.smtp.EmailBackend') # END EMAIL CONFIGURATION # MANAGER CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#admins ADMINS = values.SingleNestedTupleValue(( ('Alice', 'alice@localhost'), ('Bob', 'bob@localhost'), )) # See: https://docs.djangoproject.com/en/dev/ref/settings/#managers MANAGERS = ADMINS # END MANAGER CONFIGURATION # DATABASE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = values.DatabaseURLValue('postgres://localhost/cacao_app') # END DATABASE CONFIGURATION # CACHING # Do this here because thanks to django-pylibmc-sasl and pylibmc # memcacheify (used on heroku) is painful to install on windows. CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': '' } } # END CACHING # GENERAL CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone TIME_ZONE = 'America/Los_Angeles' # See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code LANGUAGE_CODE = 'es-NI' # See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id SITE_ID = 1 # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n USE_I18N = True # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n USE_L10N = True # See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz USE_TZ = True # END GENERAL CONFIGURATION # TEMPLATE CONFIGURATION # See: # https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors TEMPLATE_CONTEXT_PROCESSORS = ( 'django.contrib.auth.context_processors.auth', "allauth.account.context_processors.account", 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.tz', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.request', # Your stuff: custom template context processers go here 'context.guia_items', ) # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs TEMPLATE_DIRS = ( join(BASE_DIR, 'templates'), ) TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ) # STATIC FILE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root STATIC_ROOT = join(os.path.dirname(BASE_DIR), 'staticfiles') # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url STATIC_URL = '/static/' # See: # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS STATICFILES_DIRS = ( join(BASE_DIR, 'static'), ) # See: # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) # END STATIC FILE CONFIGURATION # MEDIA CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root MEDIA_ROOT = join(BASE_DIR, 'media') # See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url MEDIA_URL = '/media/' # END MEDIA CONFIGURATION # URL Configuration ROOT_URLCONF = 'urls' # See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application WSGI_APPLICATION = 'wsgi.application' # End URL Configuration # AUTHENTICATION CONFIGURATION AUTHENTICATION_BACKENDS = ( "django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend", ) # Some really nice defaults ACCOUNT_AUTHENTICATION_METHOD = "username" ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_EMAIL_VERIFICATION = "mandatory" # END AUTHENTICATION CONFIGURATION # Custom user app defaults # Select the correct user model LOGIN_REDIRECT_URL = "/" LOGIN_URL = "account_login" # END Custom user app defaults # SLUGLIFIER AUTOSLUG_SLUGIFY_FUNCTION = "slugify.slugify" # END SLUGLIFIER # LOGGING CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#logging # A sample logging configuration. The only tangible logging # performed by this configuration is to send an email to # the site admins on every HTTP 500 error when DEBUG=False. # See http://docs.djangoproject.com/en/dev/topics/logging for # more details on how to customize your logging configuration. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'handlers': { 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler' } }, 'loggers': { 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, } } # Django REST Framework hide API docs REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', ) } # END LOGGING CONFIGURATION # Your common stuff: Below this line define 3rd party library settings SUIT_CONFIG = { 'ADMIN_NAME': 'Cacao', 'SHOW_REQUIRED_ASTERISK': True, 'CONFIRM_UNSAVED_CHANGES': True, 'MENU': ( {'app': 'cacao', 'label': 'Guias de Cacao', 'icon': 'icon-leaf'}, {'app': 'configuracion', 'icon': 'icon-cog'}, {'label': 'Archivos estaticos', 'icon': 'icon-globe', 'models': ( {'label': 'Generar archivos estaticos', 'url': '/admin/static-generator/'}, )}, {'app': 'auth', 'label': 'Usuarios y Grupos', 'icon': 'icon-lock'}, {'app': 'sites', 'icon': 'icon-chevron-right'}, {'app': 'redirects', 'icon': 'icon-repeat'}, ), # misc 'LIST_PER_PAGE': 15, 'HEADER_DATE_FORMAT': 'l, j, F Y', } # CKEditor CKEDITOR_UPLOAD_PATH = "uploads/" CKEDITOR_IMAGE_BACKEND = "pillow" CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' CKEDITOR_CONFIGS = { 'default': { 'toolbar': [ ['Format', 'Bold', 'Italic', 'Underline', 'SpellChecker', '-', 'NumberedList', 'BulletedList', 'Indent', 'Outdent', 'JustifyLeft', 'JustifyCenter', '-', 'JustifyRight', 'JustifyBlock', 'PasteText', 'PasteFromWord', '-', 'Find', 'Replace', 'Cut', 'Copy', 'Paste', '-', 'Image', 'Table', 'Link', 'Unlink', 'SectionLink', 'Undo', 'Redo', 'Source', 'Maximize', ], ], 'width': 'auto', 'allowedContent': True, 'removePlugins': 'stylesheetparser', 'extraAllowedContent': 'iframe[*]', }, } # FB App ID FB_APP_ID = values.SecretValue() # GA APP ID GA_APP_ID = values.SecretValue() # used for the views delete folders and open the guide folder PROJECT_DIR = dirname(dirname(abspath(__file__))) PERSEUS_BUILD_DIR = '/tmp/perseus/build' PERSEUS_SOURCE_DIR = '/tmp/perseus/guia' # config for create pdf's PDF_KIT_MODEL = 'cacao.Content'
class NginxSecureStatic(object): USE_X_ACCEL_REDIRECT = True X_ACCEL_REDIRECT_PREFIX = values.Value('/protected')
class Test(Base): DEBUG = False TEMPLATE_DEBUG = True def _fake_convert_pdf(self, infile, outpath): _, filename = os.path.split(infile) name, ext = filename.rsplit('.', 1) output = os.path.join(outpath, '%s.pdf' % name) args = ['cp', infile, output] return args, output @property def FROIDE_CONFIG(self): config = dict(super(Test, self).FROIDE_CONFIG) config.update( dict(doc_conversion_call_func=self._fake_convert_pdf, default_law=10000, greetings=[ rec(u"Dear ((?:Mr\.?|Ms\.?) .*),?"), rec(u'Sehr geehrter? ((Herr|Frau) .*),?') ], closings=[ rec(u"Sincerely yours,?"), rec(u'Mit freundlichen Grüßen') ], public_body_officials_public=False)) return config @property def MEDIA_ROOT(self): return os.path.abspath( os.path.join(super(Test, self).PROJECT_ROOT, "tests", "testdata")) MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' CACHES = values.CacheURLValue('locmem://') TEST_SELENIUM_DRIVER = values.Value('phantomjs') USE_X_ACCEL_REDIRECT = True SECRET_URLS = values.DictValue({ "admin": "admin", "postmark_inbound": "postmark_inbound", "postmark_bounce": "postmark_bounce" }) EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' DEFAULT_FROM_EMAIL = '*****@*****.**' FOI_EMAIL_DOMAIN = 'fragdenstaat.de' HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', 'URL': 'http://127.0.0.1:9200/', 'INDEX_NAME': 'froide', }, } CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend' CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler" CELERY_ALWAYS_EAGER = True CELERY_EAGER_PROPAGATES_EXCEPTIONS = True MIDDLEWARE_CLASSES = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ]
class BaseConfiguration(Configuration): BASE_DIR = os.getcwd() ROOT_URLCONF = values.Value(None) SITE_ID = values.IntegerValue(None) # CORE DEBUG = values.BooleanValue(default=getvalue('DEBUG')) DEBUG_PROPAGATE_EXCEPTIONS = values.BooleanValue( default=getvalue('DEBUG_PROPAGATE_EXCEPTIONS')) INTERNAL_IPS = values.ListValue(default=getvalue('INTERNAL_IPS')) ALLOWED_HOSTS = values.ListValue(default=getvalue('ALLOWED_HOSTS')) TIME_ZONE = values.Value(default=getvalue('TIME_ZONE')) USE_TZ = values.Value(default=getvalue('USE_TZ')) LANGUAGE_CODE = values.Value(default=getvalue('LANGUAGE_CODE')) LANGUAGES_BIDI = values.Value(default=getvalue('LANGUAGES_BIDI')) USE_I18N = values.Value(default=getvalue('USE_I18N')) LOCALE_PATHS = values.ListValue(default=getvalue('LOCALE_PATHS')) USE_L10N = values.Value(default=getvalue('USE_L10N')) DEFAULT_CHARSET = values.Value(default=getvalue('DEFAULT_CHARSET')) SERVER_EMAIL = values.Value(default=getvalue('SERVER_EMAIL')) DATABASE_ROUTERS = values.Value(default=getvalue('DATABASE_ROUTERS')) EMAIL_BACKEND = values.Value(default=getvalue('EMAIL_BACKEND')) EMAIL_HOST = values.Value(default=getvalue('EMAIL_HOST')) EMAIL_PORT = values.IntegerValue(default=getvalue('EMAIL_PORT')) INSTALLED_APPS = values.ListValue(default=getvalue('INSTALLED_APPS')) FORM_RENDERER = values.Value(default=getvalue('FORM_RENDERER')) DISALLOWED_USER_AGENTS = values.Value( default=getvalue('DISALLOWED_USER_AGENTS')) IGNORABLE_404_URLS = values.Value(default=getvalue('IGNORABLE_404_URLS')) SECRET_KEY = values.SecretValue() DEFAULT_FILE_STORAGE = values.Value( default=getvalue('DEFAULT_FILE_STORAGE')) MEDIA_ROOT = values.Value(default=getvalue('MEDIA_ROOT')) MEDIA_URL = values.Value(default=getvalue('MEDIA_URL')) STATIC_ROOT = values.Value(default=getvalue('STATIC_ROOT')) STATIC_URL = values.Value(default=getvalue('STATIC_URL')) FILE_UPLOAD_HANDLERS = values.ListValue( default=getvalue('FILE_UPLOAD_HANDLERS')) FILE_UPLOAD_MAX_MEMORY_SIZE = values.IntegerValue( default=getvalue('FILE_UPLOAD_MAX_MEMORY_SIZE')) DATA_UPLOAD_MAX_MEMORY_SIZE = values.IntegerValue( default=getvalue('DATA_UPLOAD_MAX_MEMORY_SIZE')) DATA_UPLOAD_MAX_NUMBER_FIELDS = values.IntegerValue( default=getvalue('DATA_UPLOAD_MAX_NUMBER_FIELDS')) FILE_UPLOAD_TEMP_DIR = values.Value( default=getvalue('FILE_UPLOAD_TEMP_DIR')) STATICFILES_DIRS = values.ListValue(default=getvalue('STATICFILES_DIRS')) WSGI_APPLICATION = values.Value(default=getvalue('WSGI_APPLICATION')) # MIDDLEWARE MIDDLEWARE = values.ListValue(default=getvalue('MIDDLEWARE')) # AUTHENTICATION AUTH_USER_MODEL = values.Value(default=getvalue('AUTH_USER_MODEL')) AUTHENTICATION_BACKENDS = values.ListValue( default=getvalue('AUTHENTICATION_BACKENDS')) LOGIN_URL = values.Value(default=getvalue('LOGIN_URL')) LOGIN_REDIRECT_URL = values.Value(default=getvalue('LOGIN_REDIRECT_URL')) LOGOUT_REDIRECT_URL = values.Value(default=getvalue('LOGOUT_REDIRECT_URL')) PASSWORD_RESET_TIMEOUT_DAYS = values.IntegerValue( default=getvalue('PASSWORD_RESET_TIMEOUT_DAYS')) PASSWORD_RESET_TIMEOUT = values.IntegerValue( default=getvalue('PASSWORD_RESET_TIMEOUT')) PASSWORD_HASHERS = values.ListValue(default=getvalue('PASSWORD_HASHERS')) AUTH_PASSWORD_VALIDATORS = values.ListValue( default=getvalue('AUTH_PASSWORD_VALIDATORS')) # SIGNING SIGNING_BACKEND = values.Value(default=getvalue('SIGNING_BACKEND')) # CSRF CSRF_FAILURE_VIEW = values.Value(default=getvalue('CSRF_FAILURE_VIEW')) CSRF_COOKIE_NAME = values.Value(default=getvalue('CSRF_COOKIE_NAME')) CSRF_COOKIE_AGE = values.IntegerValue(default=getvalue('CSRF_COOKIE_AGE')) CSRF_COOKIE_DOMAIN = values.Value(default=getvalue('CSRF_COOKIE_DOMAIN')) CSRF_COOKIE_PATH = values.Value(default=getvalue('CSRF_COOKIE_PATH')) CSRF_COOKIE_SECURE = values.BooleanValue( default=getvalue('CSRF_COOKIE_SECURE')) CSRF_COOKIE_HTTPONLY = values.BooleanValue( default=getvalue('CSRF_COOKIE_HTTPONLY')) CSRF_COOKIE_SAMESITE = values.Value( default=getvalue('CSRF_COOKIE_SAMESITE')) CSRF_HEADER_NAME = values.Value(default=getvalue('CSRF_HEADER_NAME')) CSRF_TRUSTED_ORIGINS = values.ListValue( default=getvalue('CSRF_TRUSTED_ORIGINS')) CSRF_USE_SESSIONS = values.BooleanValue( default=getvalue('CSRF_USE_SESSIONS')) # MESSAGES MESSAGE_STORAGE = values.Value(default=getvalue('MESSAGE_STORAGE')) # LOGGING LOGGING_CONFIG = values.Value(default=getvalue('LOGGING_CONFIG')) DEFAULT_EXCEPTION_REPORTER = values.Value( default=getvalue('DEFAULT_EXCEPTION_REPORTER')) DEFAULT_EXCEPTION_REPORTER_FILTER = values.Value( default=getvalue('DEFAULT_EXCEPTION_REPORTER_FILTER')) # TESTING TEST_RUNNER = values.Value(default=getvalue('TEST_RUNNER')) TEST_NON_SERIALIZED_APPS = values.ListValue( default=getvalue('TEST_NON_SERIALIZED_APPS')) # FIXTURES FIXTURE_DIRS = values.ListValue(default=getvalue('FIXTURE_DIRS')) # STATICFILES STATICFILES_DIRS = values.ListValue(default=getvalue('STATICFILES_DIRS')) STATICFILES_STORAGE = values.Value(default=getvalue('STATICFILES_STORAGE')) STATICFILES_FINDERS = values.ListValue( default=getvalue('STATICFILES_FINDERS')) # SYSTEM CHECKS SILENCED_SYSTEM_CHECKS = values.ListValue( default=getvalue('SILENCED_SYSTEM_CHECKS')) # SECURITY MIDDLEWARE SECURE_BROWSER_XSS_FILTER = values.BooleanValue( default=getvalue('SECURE_BROWSER_XSS_FILTER')) SECURE_CONTENT_TYPE_NOSNIFF = values.BooleanValue( default=getvalue('SECURE_CONTENT_TYPE_NOSNIFF')) SECURE_HSTS_INCLUDE_SUBDOMAINS = values.BooleanValue( default=getvalue('SECURE_HSTS_INCLUDE_SUBDOMAINS')) SECURE_HSTS_PRELOAD = values.BooleanValue( default=getvalue('SECURE_HSTS_PRELOAD')) SECURE_HSTS_SECONDS = values.IntegerValue( default=getvalue('SECURE_HSTS_SECONDS')) SECURE_REDIRECT_EXEMPT = values.ListValue( default=getvalue('SECURE_REDIRECT_EXEMPT')) SECURE_REFERRER_POLICY = values.Value( default=getvalue('SECURE_REFERRER_POLICY')) SECURE_SSL_HOST = values.Value(default=getvalue('SECURE_SSL_HOST')) SECURE_SSL_REDIRECT = values.BooleanValue( default=getvalue('SECURE_SSL_REDIRECT')) @classmethod def pre_setup(cls): super(BaseConfiguration, cls).pre_setup() if cls.DEBUG: cls.ALLOWED_HOSTS = ['*']
class TestBase(Base): DEBUG = False PASSWORD_HASHERS = [ 'django.contrib.auth.hashers.MD5PasswordHasher', ] ELASTICSEARCH_DSL_SIGNAL_PROCESSOR = 'django_elasticsearch_dsl.signals.BaseSignalProcessor' @property def TEMPLATES(self): TEMP = super().TEMPLATES TEMP[0]['OPTIONS']['debug'] = True return TEMP def _fake_convert_pdf(self, infile, outpath): _, filename = os.path.split(infile) name, ext = filename.rsplit('.', 1) output = os.path.join(outpath, '%s.pdf' % name) args = ['cp', infile, output] return args, output @property def FROIDE_CONFIG(self): config = dict(super().FROIDE_CONFIG) config.update(dict( spam_protection=False, doc_conversion_call_func=self._fake_convert_pdf, default_law=10000, greetings=[rec(r"Dear ((?:Mr\.?|Ms\.?) .*),?"), rec(r'Sehr geehrter? ((Herr|Frau) .*),?')], closings=[rec(r"Sincerely yours,?"), rec(r'Mit freundlichen Grüßen')], public_body_officials_public=False )) return config @property def MEDIA_ROOT(self): return os.path.abspath(os.path.join(super().PROJECT_ROOT, "tests", "testdata")) ALLOWED_HOSTS = ('localhost', 'testserver') ELASTICSEARCH_INDEX_PREFIX = 'froide_test' MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' CACHES = values.CacheURLValue('locmem://') TEST_SELENIUM_DRIVER = values.Value('chrome_headless') SECRET_URLS = values.DictValue({ "admin": "admin", "postmark_inbound": "postmark_inbound", "postmark_bounce": "postmark_bounce" }) EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' DEFAULT_FROM_EMAIL = '*****@*****.**' FOI_EMAIL_DOMAIN = 'fragdenstaat.de' CELERY_TASK_ALWAYS_EAGER = True CELERY_TASK_EAGER_PROPAGATES = True MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ] FROIDE_CSRF_MIDDLEWARE = 'django.middleware.csrf.CsrfViewMiddleware'
class Base(StyleguideMixin, DRFMixin, RichieCoursesConfigurationMixin, Configuration): """ This is the base configuration every configuration (aka environnement) should inherit from. It is recommended to configure third-party applications by creating a configuration mixins in ./configurations and compose the Base configuration with those mixins. It depends on an environment variable that SHOULD be defined: * DJANGO_SECRET_KEY You may also want to override default configuration by setting the following environment variables: * DJANGO_SENTRY_DSN * RICHIE_ES_HOST * DB_NAME * DB_HOST * DB_PASSWORD * DB_PORT * DB_USER """ DEBUG = False SITE_ID = 1 # Security ALLOWED_HOSTS = values.ListValue([]) SECRET_KEY = "ThisIsAnExampleKeyForDevPurposeOnly" # nosec # Application definition ROOT_URLCONF = "funcampus.urls" WSGI_APPLICATION = "funcampus.wsgi.application" # Database DATABASES = { "default": { "ENGINE": values.Value( "django.db.backends.postgresql_psycopg2", environ_name="DB_ENGINE", environ_prefix=None, ), "NAME": values.Value("funcampus", environ_name="DB_NAME", environ_prefix=None), "USER": values.Value("funcampus", environ_name="DB_USER", environ_prefix=None), "PASSWORD": values.Value("pass", environ_name="DB_PASSWORD", environ_prefix=None), "HOST": values.Value("localhost", environ_name="DB_HOST", environ_prefix=None), "PORT": values.Value(5432, environ_name="DB_PORT", environ_prefix=None), } } MIGRATION_MODULES = {} # Static files (CSS, JavaScript, Images) STATIC_URL = "/static/" MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(DATA_DIR, "media") STATIC_ROOT = os.path.join(DATA_DIR, "static") # For static files, we want to use a backend that includes a hash in # the filename, that is calculated from the file content, so that browsers always # get the updated version of each file. STATICFILES_STORAGE = values.Value( "base.storage.CDNManifestStaticFilesStorage") # Login/registration related settings LOGIN_REDIRECT_URL = "/" LOGOUT_REDIRECT_URL = "/" # Internationalization TIME_ZONE = "Europe/Paris" USE_I18N = True USE_L10N = True USE_TZ = True LOCALE_PATHS = [os.path.join(BASE_DIR, "locale")] # Templates TEMPLATES = [{ "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [os.path.join(BASE_DIR, "templates")], "OPTIONS": { "context_processors": [ "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", "django.template.context_processors.i18n", "django.template.context_processors.debug", "django.template.context_processors.request", "django.template.context_processors.media", "django.template.context_processors.csrf", "django.template.context_processors.tz", "sekizai.context_processors.sekizai", "django.template.context_processors.static", "cms.context_processors.cms_settings", "richie.apps.core.context_processors.site_metas", ], "loaders": [ "django.template.loaders.filesystem.Loader", "django.template.loaders.app_directories.Loader", ], }, }] MIDDLEWARE = ( "richie.apps.core.cache.LimitBrowserCacheTTLHeaders", "cms.middleware.utils.ApphookReloadMiddleware", "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.locale.LocaleMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "dockerflow.django.middleware.DockerflowMiddleware", "cms.middleware.user.CurrentUserMiddleware", "cms.middleware.page.CurrentPageMiddleware", "cms.middleware.toolbar.ToolbarMiddleware", "cms.middleware.language.LanguageCookieMiddleware", "dj_pagination.middleware.PaginationMiddleware", ) # Django applications from the highest priority to the lowest INSTALLED_APPS = ( # funcampus stuff "base", # Richie stuff "richie.apps.demo", "richie.apps.search", "richie.apps.courses", "richie.apps.core", "richie.plugins.glimpse", "richie.plugins.html_sitemap", "richie.plugins.large_banner", "richie.plugins.nesteditem", "richie.plugins.plain_text", "richie.plugins.section", "richie.plugins.simple_picture", "richie.plugins.simple_text_ckeditor", "richie", # Third party apps "dj_pagination", "dockerflow.django", "parler", "rest_framework", "storages", # Django-cms "djangocms_admin_style", "djangocms_googlemap", "djangocms_link", "djangocms_picture", "djangocms_text_ckeditor", "djangocms_video", "cms", "menus", "sekizai", "treebeard", "filer", "easy_thumbnails", # Django "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.admin", "django.contrib.sites", "django.contrib.sitemaps", "django.contrib.staticfiles", "django.contrib.messages", ) # Search RICHIE_FILTERS_CONFIGURATION = [ ( "richie.apps.search.filter_definitions.IndexableMPTTFilterDefinition", { "human_name": _("Diplomas"), "is_autocompletable": True, "is_searchable": True, "min_doc_count": 0, "name": "diplomas", "position": 1, "reverse_id": "diplomas", "term": "categories", }, ), ( "richie.apps.search.filter_definitions.IndexableMPTTFilterDefinition", { "human_name": _("Domains and mentions"), "is_autocompletable": True, "is_searchable": True, "min_doc_count": 0, "name": "domains", "position": 2, "reverse_id": "domains", "term": "categories", }, ), ( "richie.apps.search.filter_definitions.IndexableMPTTFilterDefinition", { "human_name": _("Levels"), "is_autocompletable": True, "is_searchable": True, "min_doc_count": 0, "name": "levels", "position": 3, "reverse_id": "levels", "term": "categories", }, ), ( "richie.apps.search.filter_definitions.IndexableMPTTFilterDefinition", { "human_name": _("Skills"), "is_autocompletable": True, "is_searchable": True, "min_doc_count": 0, "name": "skills", "position": 4, "reverse_id": "skills", "term": "categories", }, ), ] # Languages # - Django LANGUAGE_CODE = "fr" # Careful! Languages should be ordered by priority, as this tuple is used to get # fallback/default languages throughout the app. # Use "en" as default as it is the language that is most likely to be spoken by any visitor # when their preferred language, whatever it is, is unavailable LANGUAGES = (("en", _("English")), ("fr", _("French"))) # - Django CMS CMS_LANGUAGES = { "default": { "public": True, "hide_untranslated": False, "redirect_on_fallback": True, "fallbacks": ["en", "fr"], }, 1: [ { "public": False, "code": "en", "hide_untranslated": False, "name": _("English"), "fallbacks": ["fr"], "redirect_on_fallback": True, }, { "public": True, "code": "fr", "hide_untranslated": False, "name": _("French"), "fallbacks": ["en"], "redirect_on_fallback": True, }, ], } # - Django Parler PARLER_LANGUAGES = CMS_LANGUAGES # Permisions # - Django CMS CMS_PERMISSION = True # - Django Filer FILER_ENABLE_PERMISSIONS = True FILER_IS_PUBLIC_DEFAULT = True # - Django Pagination PAGINATION_INVALID_PAGE_RAISES_404 = True PAGINATION_DEFAULT_WINDOW = 2 PAGINATION_DEFAULT_MARGIN = 1 # Logging LOGGING = { "version": 1, "disable_existing_loggers": True, "formatters": { "verbose": { "format": "%(levelname)s %(asctime)s %(module)s " "%(process)d %(thread)d %(message)s" } }, "handlers": { "console": { "level": "DEBUG", "class": "logging.StreamHandler", "formatter": "verbose", } }, "loggers": { "django.db.backends": { "level": "ERROR", "handlers": ["console"], "propagate": False, } }, } # Demo RICHIE_DEMO_SITE_DOMAIN = "localhost:8080" RICHIE_DEMO_FIXTURES_DIR = os.path.join(BASE_DIR, "base", "fixtures") # Elasticsearch RICHIE_ES_HOST = values.Value("elasticsearch", environ_name="RICHIE_ES_HOST", environ_prefix=None) RICHIE_ES_INDICES_PREFIX = values.Value( default="richie", environ_name="RICHIE_ES_INDICES_PREFIX", environ_prefix=None) # Cache CACHES = values.DictValue({ "default": { "BACKEND": values.Value( "django_redis.cache.RedisCache", environ_name="CACHE_DEFAULT_BACKEND", environ_prefix=None, ), "LOCATION": values.Value( "mymaster/redis-sentinel:26379,redis-sentinel:26379/0", environ_name="CACHE_DEFAULT_LOCATION", environ_prefix=None, ), "OPTIONS": values.DictValue( {"CLIENT_CLASS": "richie.apps.core.cache.SentinelClient"}, environ_name="CACHE_DEFAULT_OPTIONS", environ_prefix=None, ), "TIMEOUT": values.IntegerValue( 300, environ_name="CACHE_DEFAULT_TIMEOUT", environ_prefix=None, ), } }) # For more details about CMS_CACHE_DURATION, see : # http://docs.django-cms.org/en/latest/reference/configuration.html#cms-cache-durations CMS_CACHE_DURATIONS = values.DictValue({ "menus": 3600, "content": 86400, "permissions": 86400 }) MAX_BROWSER_CACHE_TTL = 600 # Sessions SESSION_ENGINE = values.Value("django.contrib.sessions.backends.cache") # Sentry SENTRY_DSN = values.Value(None, environ_name="SENTRY_DSN") # pylint: disable=invalid-name @property def ENVIRONMENT(self): """Environment in which the application is launched.""" return self.__class__.__name__.lower() # pylint: disable=invalid-name @property def RELEASE(self): """ Return the release information. Delegate to the module function to enable easier testing. """ return get_release() @classmethod def post_setup(cls): """Post setup configuration. This is the place where you can configure settings that require other settings to be loaded. """ super().post_setup() # The SENTRY_DSN setting should be available to activate sentry for an environment if cls.SENTRY_DSN is not None: sentry_sdk.init( dsn=cls.SENTRY_DSN, environment=cls.ENVIRONMENT, release=cls.RELEASE, integrations=[DjangoIntegration()], ) with sentry_sdk.configure_scope() as scope: scope.set_extra("application", "backend")
class Base(Configuration): BASE_DIR = Path(__file__).absolute().parent.parent SECRET_KEY = values.Value("secret") ALLOWED_HOSTS = ["localhost"] INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "django_extensions", "colorfield", "recurrence", "rest_framework", "rest_framework.authtoken", "django_filters", "storages", "apps.authentication", "apps.customer", "apps.task", "apps.report", "apps.invoice", "apps.flat", "apps.api", ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] ROOT_URLCONF = "maestro.urls" WSGI_APPLICATION = "maestro.wsgi.application" AUTH_USER_MODEL = "authentication.User" DATABASE_NAME = values.Value("maestro_development") DATABASE_ENGINE = values.Value("django.db.backends.postgresql_psycopg2") DATABASE_USER = values.Value("") DATABASE_PASSWORD = values.Value("") DATABASE_HOST = values.Value("localhost") DATABASE_PORT = values.Value("") DATABASE_OPTIONS = values.DictValue({}) @property def DATABASES(self): return { "default": { "ENGINE": self.DATABASE_ENGINE, "NAME": self.DATABASE_NAME, "USER": self.DATABASE_USER, "PASSWORD": self.DATABASE_PASSWORD, "HOST": self.DATABASE_HOST, "PORT": self.DATABASE_PORT, "OPTIONS": self.DATABASE_OPTIONS, "ATOMIC_REQUESTS": True, } } AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" # noqa }, { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator" }, { "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator" }, { "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator" }, ] DEFAULT_AUTO_FIELD = "django.db.models.AutoField" LANGUAGE_CODE = "de-CH" USE_I18N = True USE_L10N = True X_FRAME_OPTIONS = "ALLOWALL" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] REST_FRAMEWORK = { "DEFAULT_PAGINATION_CLASS": "apps.api.pagination.PageNumberPagination", "PAGE_SIZE": 100, "DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend", ), "DEFAULT_AUTHENTICATION_CLASSES": [ "rest_framework.authentication.TokenAuthentication", ], "DEFAULT_PERMISSION_CLASSES": [ "rest_framework.permissions.IsAuthenticated", ], } LOGGING = { "version": 1, "disable_existing_loggers": False, "formatters": { "verbose": { "format": ("%(asctime)s [%(process)d] [%(levelname)s] " "pathname=%(pathname)s lineno=%(lineno)s " "funcname=%(funcName)s %(message)s"), "datefmt": "%Y-%m-%d %H:%M:%S", }, "simple": { "format": "%(levelname)s %(message)s" }, }, "handlers": { "null": { "level": "DEBUG", "class": "logging.NullHandler", }, "console": { "level": "INFO", "class": "logging.StreamHandler", "formatter": "verbose", }, }, "loggers": { "django": { "handlers": ["console"], "level": "DEBUG", "propagate": True, }, "django.request": { "handlers": ["console"], "level": "DEBUG", "propagate": False, }, "django.db.backends": { "handlers": ["console"], "level": "DEBUG", "propagate": False, }, }, }
class Base(Configuration): ''' All configurations should sublcass this base class. This contains all that is required, aside from custom endpoints that will vary per deployment and/or environment. Defaults have been set to err on the side of caution, so DEBUG, ADMIN, etc will have to be explictly turned on where necessary. ''' # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # THIS IS JUST A DEFAULT THAT WAS GENERATED FOR LOCAL DEVELOPMENT # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = values.Value('abceasyas123') # SECURITY WARNING: don't run with debug turned on in production! DEBUG = values.BooleanValue(False) ADMIN_ENABLED = values.BooleanValue(False) SESSION_EXPIRE_AT_BROWSER_CLOSE = values.BooleanValue(True) AUTH_USER_MODEL = values.Value('users.User') MEMBERSHIP_ENCODE_KEY = values.Value('') MEMBERSHIP_RENEWAL_URL_BASE = values.URLValue('') SHARED_SESSION_SITES = values.ListValue([]) SESSION_COOKIE_DOMAIN = values.Value() SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') ALLOWED_HOSTS = values.ListValue([]) SITE_ID = values.IntegerValue(1) ADMINS = [('Sir Terence', '*****@*****.**')] SERVER_EMAIL = '*****@*****.**' # SESSION_COOKIE_AGE = 60*60*24 X_FRAME_OPTIONS = 'ALLOW' INSTALLED_APPS = values.ListValue([ # Django packages 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', 'django.contrib.sitemaps', # External packages 'captcha', 'debug_toolbar', 'django_jinja', 'raven.contrib.django.raven_compat', 'rest_framework_swagger', 'rest_framework.authtoken', 'rest_framework', 'rosetta', 'shared_session', 'storages', 'webpack_loader', 'cacheops', 'robots', 'import_export', # Application packages 'clublink.base', 'clublink.certificates', 'clublink.clubs', 'clublink.cms', 'clublink.corp', 'clublink.landings', 'clublink.users', 'clublink.emails', ]) MIDDLEWARE = values.ListValue([ 'debug_toolbar.middleware.DebugToolbarMiddleware', # Custom middleware 'clublink.base.middleware.HostnameRoutingMiddleware', 'clublink.base.middleware.ShortCircuitMiddleware', # Django middleware 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # Sites middleware 'django.contrib.sites.middleware.CurrentSiteMiddleware', # Custom middleware 'clublink.base.middleware.SpoofedUserMiddleware', 'clublink.base.middleware.ScaffoldingMiddleware', 'clublink.base.middleware.LocaleMiddleware' ]) ROOT_URLCONF = values.Value('clublink.urls.common') TEMPLATES = values.ListValue([ { 'BACKEND': 'django_jinja.backend.Jinja2', 'DIRS': [ 'templates', ], 'APP_DIRS': True, 'OPTIONS': { 'match_regex': '.+(\.jinja|\.txt)', 'match_extension': None, 'extensions': DEFAULT_EXTENSIONS + [ 'webpack_loader.contrib.jinja2ext.WebpackExtension', 'jinja2.ext.i18n', 'cacheops.jinja2.cache', 'clublink.base.extensions.SharedSession', ], 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.tz', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', # Custom context processors 'clublink.base.context_processors.globals' ], } }, { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, } ]) WSGI_APPLICATION = values.Value('clublink.wsgi.application') CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': values.Value('redis://127.0.0.1:6379/1', environ_name='CACHES_DEFAULT_LOCATION'), 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', } } } # Database # https://docs.djangoproject.com/en/1.11/ref/settings/# # As per: https://github.com/kennethreitz/dj-database-url#url-schema ### <-----------------------------------------------------------------> ### ### NOTE!!!! THIS IS THE ONE VALUE THAT IS NOT PREFIXED WITH DJANGO_ ### # DATABASE_DICT = values.DictValue() # LEGACY_DATABASE_DICT = values.DictValue() ### <-----------------------------------------------------------------> ### DATABASE_ENGINE = values.Value("django.db.backends.mysql") DATABASE_NAME = values.Value() DATABASE_USER = values.Value() DATABASE_PASSWORD = values.Value() DATABASE_HOST = values.Value() DATABASE_PORT = values.Value('3306') LEGACY_DATABASE_ENGINE = values.Value("django.db.backends.mysql") LEGACY_DATABASE_NAME = values.Value() LEGACY_DATABASE_USER = values.Value() LEGACY_DATABASE_PASSWORD = values.Value() LEGACY_DATABASE_HOST = values.Value() LEGACY_DATABASE_PORT = values.Value('3306') @property def DATABASES(self): DATABASES = { 'default': { 'ENGINE': self.DATABASE_ENGINE, 'NAME': self.DATABASE_NAME, 'USER': self.DATABASE_USER, 'PASSWORD': self.DATABASE_PASSWORD, 'HOST': self.DATABASE_HOST, 'PORT': self.DATABASE_PORT } } return DATABASES # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = values.ListValue([ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ]) # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = values.Value('en') LANGUAGES = values.SingleNestedTupleValue(( ('en', _('English')), ('fr', _('French')), )) LOCALE_PATHS = values.SingleNestedTupleValue( (os.path.join(BASE_DIR, 'locale'), )) TIME_ZONE = values.Value('America/Toronto') USE_I18N = values.BooleanValue(True) USE_L10N = values.BooleanValue(True) USE_TZ = values.BooleanValue(True) # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ DEFAULT_FILE_STORAGE = values.Value( 'django.contrib.staticfiles.storage.StaticFilesStorage') STATICFILES_DIRS = (os.path.join(BASE_DIR, 'assets'), ) # STATIC # STATIC_URL = values.Value('/static/') STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATICFILES_LOCATION = values.Value('static') STATICFILES_STORAGE = values.Value( 'django.contrib.staticfiles.storage.StaticFilesStorage') # ASSETS # ASSETS_URL = values.Value('/asset_files/') ASSETS_ROOT = os.path.join(BASE_DIR, 'asset_files') ASSETS_LOCATION = values.Value('assets') ASSETS_FILE_STORAGE = values.Value( 'django.contrib.staticfiles.storage.StaticFilesStorage') # MEDIA # MEDIA_URL = values.Value('/media/') MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_LOCATION = values.Value('media') # WEBPACK # WEBPACK_LOADER = values.DictValue({ 'DEFAULT': { 'BUNDLE_DIR_NAME': 'bundles/', 'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json') }, }) SWAGGER_SETTINGS = values.DictValue({ 'DOC_EXPANSION': 'list', 'JSON_EDITOR': True, }) CSRF_COOKIE_HTTPONLY = values.BooleanValue(True) SECURE_REDIRECT_EXEMPT = values.ListValue([r'^__health__/$']) GIFT_CERTIFICATE_SITE_URL = values.URLValue() CORP_SITE_URL = values.URLValue() CLUB_SITE_URL = values.Value() ADMIN_SITE_URL = values.URLValue() ADMIN_HOSTNAME = values.RegexValue(r'^admin\.') CORP_HOSTNAME = values.RegexValue(r'^(www\.)?') API_HOSTNAME = values.RegexValue(r'^api\.') GIFT_CERTIFICATE_HOSTNAME = values.RegexValue(r'^giftcertificates\.') GIFT_CARDS_HOSTNAME = values.RegexValue(r'^giftcards\.') def HOSTNAME_URLCONFS(self): return ( (self.ADMIN_HOSTNAME, 'clublink.urls.admin'), (self.CORP_HOSTNAME, 'clublink.urls.corp'), (self.API_HOSTNAME, 'clublink.urls.api'), (self.GIFT_CERTIFICATE_HOSTNAME, 'clublink.urls.gc'), (self.GIFT_CARDS_HOSTNAME, 'clublink.urls.gift_cards'), ) def HOSTNAME_LANGUAGES(self): return ( (self.ADMIN_HOSTNAME, ('en', )), (self.GIFT_CERTIFICATE_HOSTNAME, ('en', )), ) VPN_PROTECTED_VIEWS_ENABLED = values.BooleanValue(True) VPN_IP_ADDRESS = values.Value('10.8.0.1') EMAIL_HOST = values.Value() EMAIL_PORT = values.IntegerValue(587) EMAIL_HOST_USER = values.Value() EMAIL_HOST_PASSWORD = values.Value() EMAIL_USE_TLS = values.BooleanValue(True) DEFAULT_FROM_EMAIL_ADDRESS = values.EmailValue('*****@*****.**') MEMBER_SERVICES_EMAIL_ADDRESS = values.EmailValue( '*****@*****.**') GIFT_CERTIFICATE_EMAIL_ADDRESS = values.EmailValue( '*****@*****.**') CORPORATE_EVENTS_EMAIL_ADDRESS = values.EmailValue( '*****@*****.**') MEMBERSHIP_SALES_EMAIL_ADDRESS = values.EmailValue( '*****@*****.**') EVENTS_EMAIL_ADDRESSES = values.ListValue([ '*****@*****.**', '*****@*****.**', '*****@*****.**', ]) IBS_API_WSDL = values.Value() IBS_API_USER = values.Value() IBS_API_PASSWORD = values.Value() IBS_WEBRES_API_ROOT = values.Value() IBS_WEBRES_API_USER = values.Value() IBS_WEBRES_API_PASSWORD = values.Value() GOOGLE_MAPS_API_KEY = values.Value() GOOGLE_ANALYTICS_TRACKING_ID = values.Value() DEFAULT_CERTIFICATE_EMPLOYEE_NUMBER = values.Value() DEFAULT_CERTIFICATE_MEMBERSHIP_NUMBER = values.Value('') CERTIFICATES_BATCH_LIMIT = values.IntegerValue(150) DATA_UPLOAD_MAX_NUMBER_FIELDS = values.IntegerValue(1000) GIFT_CERTIFICATE_IP_WHITELIST_ENABLED = values.BooleanValue(False) GIFT_CERTIFICATE_IP_WHITELIST = values.ListValue() AES_SHARED_KEY = values.Value() DYNAMICS_HOST = values.Value() DYNAMICS_USER = values.Value() DYNAMICS_PASSWORD = values.Value() DYNAMICS_DATABASE = values.Value() NOCAPTCHA = values.BooleanValue(True) RECAPTCHA_PUBLIC_KEY = values.Value() RECAPTCHA_PRIVATE_KEY = values.Value() PASSWORD_RESET_DEBUG = values.BooleanValue(True) PASSWORD_RESET_DEBUG_EMAIL_ADDRESSES = values.ListValue() ASSETS_FILE_STORAGE = values.Value( 'django.core.files.storage.FileSystemStorage') SEARCH_ENGINE_INDEXING_DISABLED = values.BooleanValue(False) SESSION_EXPIRE_AT_BROWSER_CLOSE = values.BooleanValue(True) REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.SessionAuthentication', ), 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_RENDERER_CLASSES': ('rest_framework.renderers.JSONRenderer', ), 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 50, 'EXCEPTION_HANDLER': 'clublink.base.api.handlers.logging_exception_handler', } CELERY_BROKER_URL = values.Value() CELERY_RESULT_BACKEND = values.Value()
class Backfill: # The backfill script will write down, to disk, the last successful key # (and some metadata) when it iterates though the pages. RESUME_DISK_LOG_FILE = values.Value( "/tmp/backfill-last-successful-key.json")
class Common(Configuration): INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Third party apps 'rest_framework', # utilities for rest apis 'rest_framework.authtoken', # token authentication # 'django_rq', # asynchronous queuing 'versatileimagefield', # image manipulation # 'gdstorage', # google drive storage # Your apps 'authentication', 'users', 'courses', 'utils', ) # https://docs.djangoproject.com/en/1.8/topics/http/middleware/ MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware') ROOT_URLCONF = 'urls' SECRET_KEY = 'Not a secret' WSGI_APPLICATION = 'wsgi.application' # Email EMAIL_BACKEND = values.Value('django.core.mail.backends.smtp.EmailBackend') MANAGERS = (('Author', '*****@*****.**'), ) ADMINS = [('Shirish', '*****@*****.**'), ('Crowd Course Admin', '*****@*****.**')] # Postgres DATABASES = values.DatabaseURLValue('postgres://localhost/scholars') # General APPEND_SLASH = values.BooleanValue(False) TIME_ZONE = 'UTC' LANGUAGE_CODE = 'en-us' # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = False USE_L10N = True USE_TZ = True LOGIN_REDIRECT_URL = '/' ROOT_DIR = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # Static Files STATIC_ROOT = join(os.path.dirname(BASE_DIR), 'staticfiles') STATICFILES_DIRS = [ join(os.path.dirname(BASE_DIR), 'static'), ] STATIC_URL = '/static/' STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) # Media files MEDIA_ROOT = join(os.path.dirname(BASE_DIR), 'media') MEDIA_URL = '/media/' TEMPLATES_DIR = join(os.path.dirname(BASE_DIR), 'frontend', 'release') TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': False, 'DIRS': [TEMPLATES_DIR], 'OPTIONS': { 'context_processors': [ 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.debug', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.tz', 'django.contrib.messages.context_processors.messages' ], 'loaders': [ ('django.template.loaders.cached.Loader', [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ]), ], }, }, ] # Set DEBUG to False as a default for safety # https://docs.djangoproject.com/en/dev/ref/settings/#debug DEBUG = values.BooleanValue(False) for config in TEMPLATES: config['OPTIONS']['debug'] = DEBUG # Logging LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' }, 'simple': { 'format': '%(levelname)s %(message)s' }, 'rq_console': { 'format': '%(asctime)s %(message)s', 'datefmt': '%H:%M:%S', }, }, 'filters': { 'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', }, }, 'handlers': { 'console': { 'level': 'INFO', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'rq_console': { 'level': 'DEBUG', 'class': 'rq.utils.ColorizingStreamHandler', 'formatter': 'rq_console', 'exclude': ['%(asctime)s'], }, 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler' } }, 'loggers': { 'django': { 'handlers': ['console'], 'propagate': True, }, 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': False, }, 'rq.worker': { 'handlers': ['rq_console'], 'level': 'DEBUG' } } } # Custom user app AUTH_USER_MODEL = 'users.User' # Django Rest Framework REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': int(os.getenv('DJANGO_PAGINATION_LIMIT', 10)), 'DATETIME_FORMAT': '%Y-%m-%dT%H:%M:%S%z', 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', # 'rest_framework.renderers.BrowsableAPIRenderer', ), 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', ) } # Versatile Image Field VERSATILEIMAGEFIELD_SETTINGS = { # The amount of time, in seconds, that references to created images # should be stored in the cache. Defaults to `2592000` (30 days) 'cache_length': 2592000, 'cache_name': 'versatileimagefield_cache', 'jpeg_resize_quality': 70, 'sized_directory_name': '__sized__', 'filtered_directory_name': '__filtered__', 'placeholder_directory_name': '__placeholder__', 'create_images_on_demand': False } # django-rq # Adds dashboard link for queues in /admin, This will override the default # admin template so it may interfere with other apps that modify the # default admin template. If you're using such an app, simply remove this. RQ_SHOW_ADMIN_LINK = True # http://django-googledrive-storage.readthedocs.io/en/latest/ GOOGLE_DRIVE_STORAGE_JSON_KEY_FILE = 'gdrive-9f7d7b145768.json' GOOGLE_DRIVE_STORAGE_SERVICE_EMAIL = '*****@*****.**'
class Base(Core, Elasticsearch, BigQuery): """Settings that may change per-environment, some defaults.""" # Django SECRET_KEY = values.SecretValue() DEBUG = values.BooleanValue(default=False) ALLOWED_HOSTS = values.ListValue([]) _DATABASES = values.DatabaseURLValue( default="postgresql://localhost/buildhub2") _KINTO_DATABASES = OptionalDatabaseURLValue( default="", alias="kinto", environ_name="KINTO_DATABASE_URL") CONN_MAX_AGE = values.IntegerValue(60) @property def DATABASES(self): """Because it's not possible to set 'CONN_MAX_AGE a URL, # we patch the 'DATABASES' dict *after* django-configurations has done its thing.""" DATABASES = self._DATABASES.value.copy() if self.CONN_MAX_AGE: DATABASES["default"]["CONN_MAX_AGE"] = self.CONN_MAX_AGE if self._KINTO_DATABASES.value[self._KINTO_DATABASES.alias]: DATABASES.update(self._KINTO_DATABASES.value) return DATABASES # Logging LOGGING_USE_JSON = values.BooleanValue(True) LOGGING_DEFAULT_LEVEL = values.Value("INFO") @property def LOGGING(self): return { "version": 1, "disable_existing_loggers": False, "formatters": { "json": { "()": "dockerflow.logging.JsonLogFormatter", "logger_name": "buildhub", }, "verbose": { "format": "%(levelname)s %(asctime)s %(name)s %(message)s" }, }, "handlers": { "console": { "level": self.LOGGING_DEFAULT_LEVEL, "class": "logging.StreamHandler", "formatter": ("json" if self.LOGGING_USE_JSON else "verbose"), }, "sentry": { "level": "ERROR", "class": ("raven.contrib.django.raven_compat.handlers" ".SentryHandler"), }, "null": { "class": "logging.NullHandler" }, }, "root": { "level": "INFO", "handlers": ["sentry", "console"] }, "loggers": { "django": { "level": "WARNING", "handlers": ["console"], "propagate": False, }, "django.db.backends": { "level": "ERROR", "handlers": ["console"], "propagate": False, }, "django.request": { "level": "INFO", "handlers": ["console"], "propagate": False, }, "raven": { "level": "DEBUG", "handlers": ["console"], "propagate": False, }, "sentry.errors": { "level": "DEBUG", "handlers": ["console"], "propagate": False, }, "buildhub": { "level": "DEBUG", "handlers": ["console"], "propagate": False, }, "backoff": { "level": "INFO", "handlers": ["console"], "propagate": False, }, "markus": { "level": "INFO", "handlers": ["console"], "propagate": False, }, "elasticsearch": { "level": "ERROR", "handlers": ["console"], "propagate": False, }, "request.summary": { "handlers": ["console"], "level": "INFO", "propagate": False, }, "django.security.DisallowedHost": { "handlers": ["null"], "propagate": False, }, }, } # Security related SILENCED_SYSTEM_CHECKS = values.ListValue([ # This rule is about having "X-FRAME-OPTIONS" set to "DENY" which is # not important for Buildhub2 because it's considered NOT dangerous to # put any of this data inside an iframe. "security.W019", # There are no POST endpoints that *change* data that is exposed. # I.e. you can't CSRF attack this site because there's no URL to do so # with. "security.W003", # Don't require SECURE_SSL_REDIRECT to be true. # Our load balancer talks to Django directly, via /__lbheartbeat__, # and it will 301 redirect if you don't convince it that the request # is HTTPS with `X-Forwarded-Proto: https` header. Basically, this # header can't be set in the load balancer. # If we disable the SECURE_SSL_REDIRECT (in other words omit setting it) # the /__heartbeat__ will complain and thus we can't use that endpoint # for our regular monitoring. # See https://github.com/mozilla-services/buildhub2/issues/411 "security.W008", ]) SECURE_HSTS_SECONDS = values.IntegerValue(3600) SECURE_HSTS_INCLUDE_SUBDOMAINS = values.BooleanValue(True) SECURE_HSTS_PRELOAD = values.BooleanValue(True) SECURE_CONTENT_TYPE_NOSNIFF = values.BooleanValue(True) SECURE_BROWSER_XSS_FILTER = values.BooleanValue(True)
class Production(Common): ########## INSTALLED_APPS INSTALLED_APPS = Common.INSTALLED_APPS ########## END INSTALLED_APPS ########## SECRET KEY SECRET_KEY = values.SecretValue() ########## END SECRET KEY ########## django-secure INSTALLED_APPS += ("djangosecure", ) # set this to 60 seconds and then to 518400 when you can prove it works SECURE_HSTS_SECONDS = 60 SECURE_HSTS_INCLUDE_SUBDOMAINS = values.BooleanValue(True) SECURE_FRAME_DENY = values.BooleanValue(True) SECURE_CONTENT_TYPE_NOSNIFF = values.BooleanValue(True) SECURE_BROWSER_XSS_FILTER = values.BooleanValue(True) SESSION_COOKIE_SECURE = values.BooleanValue(False) SESSION_COOKIE_HTTPONLY = values.BooleanValue(True) SECURE_SSL_REDIRECT = values.BooleanValue(True) ########## end django-secure ########## SITE CONFIGURATION # Hosts/domain names that are valid for this site # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts ALLOWED_HOSTS = ["*"] ########## END SITE CONFIGURATION INSTALLED_APPS += ("gunicorn", ) ########## STORAGE CONFIGURATION # See: http://django-storages.readthedocs.org/en/latest/index.html INSTALLED_APPS += ('storages', ) # See: http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html#settings STATICFILES_STORAGE = DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' # See: http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html#settings AWS_ACCESS_KEY_ID = values.SecretValue() AWS_SECRET_ACCESS_KEY = values.SecretValue() AWS_STORAGE_BUCKET_NAME = values.SecretValue() AWS_AUTO_CREATE_BUCKET = True AWS_QUERYSTRING_AUTH = False # AWS cache settings, don't change unless you know what you're doing: AWS_EXPIREY = 60 * 60 * 24 * 7 AWS_HEADERS = { 'Cache-Control': 'max-age=%d, s-maxage=%d, must-revalidate' % (AWS_EXPIREY, AWS_EXPIREY) } # See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url STATIC_URL = 'https://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME ########## END STORAGE CONFIGURATION ########## EMAIL DEFAULT_FROM_EMAIL = values.Value( '{{cookiecutter.project_name}} <{{cookiecutter.project_name}}-noreply@{{cookiecutter.domain_name}}>' ) EMAIL_HOST = values.Value('smtp.sendgrid.com') EMAIL_HOST_PASSWORD = values.SecretValue(environ_prefix="", environ_name="SENDGRID_PASSWORD") EMAIL_HOST_USER = values.SecretValue(environ_prefix="", environ_name="SENDGRID_USERNAME") EMAIL_PORT = values.IntegerValue(587, environ_prefix="", environ_name="EMAIL_PORT") EMAIL_SUBJECT_PREFIX = values.Value('[{{cookiecutter.project_name}}] ', environ_name="EMAIL_SUBJECT_PREFIX") EMAIL_USE_TLS = True SERVER_EMAIL = EMAIL_HOST_USER ########## END EMAIL ########## TEMPLATE CONFIGURATION # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs TEMPLATE_LOADERS = (('django.template.loaders.cached.Loader', ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', )), ) ########## END TEMPLATE CONFIGURATION ########## CACHING # Only do this here because thanks to django-pylibmc-sasl and pylibmc memcacheify is painful to install on windows. CACHES = values.CacheURLValue(default="memcached://127.0.0.1:11211")
class Core(Configuration): """Configuration that will never change per-environment.""" #: The directory in which the settings file reside. THIS_DIR = os.path.dirname(os.path.abspath(__file__)) #: Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(THIS_DIR) #: The current GLAM version. VERSION = get_version(BASE_DIR) #: Using the default first site found by django.contrib.sites SITE_ID = 1 #: The installed apps. INSTALLED_APPS = [ # Run whitenoise with runserver "whitenoise.runserver_nostatic", # Project specific apps "glam.apps.GlamAppConfig", "glam.api", # Third party apps "dockerflow.django", # Django apps "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.staticfiles", ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "dockerflow.django.middleware.DockerflowMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] ROOT_URLCONF = "glam.urls" WSGI_APPLICATION = "glam.wsgi.application" DEFAULT_FROM_EMAIL = "*****@*****.**" # Internationalization # https://docs.djangoproject.com/en/1.9/topics/i18n/ LANGUAGE_CODE = "en-us" TIME_ZONE = "UTC" USE_I18N = False USE_L10N = False USE_TZ = True DATETIME_FORMAT = "Y-m-d H:i" # simplified ISO format since we assume UTC STATICFILES_DIRS = [ os.path.join(BASE_DIR, "public"), ] STATIC_ROOT = values.Value( default=os.path.join(BASE_DIR, "public", "static")) STATIC_URL = "/static/" # the directory to have Whitenoise serve automatically on the root of the URL WHITENOISE_ROOT = STATIC_ROOT SILENCED_SYSTEM_CHECKS = [ # We can't set SECURE_HSTS_INCLUDE_SUBDOMAINS since this runs under a # mozilla.org subdomain "security.W005", "security.W009", # we know the SECRET_KEY is strong ] TEMPLATES = [{ "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [os.path.join(BASE_DIR, "public")], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }] # Django REST Framework REST_FRAMEWORK = { "DEFAULT_PARSER_CLASSES": ["drf_orjson_renderer.parsers.ORJSONParser"], "DEFAULT_RENDERER_CLASSES": ["drf_orjson_renderer.renderers.ORJSONRenderer"], "DATETIME_FORMAT": "%Y-%m-%dT%H:%M:%S", } GA_TRACKING_ID = values.Value("", environ_name="GA_TRACKING_ID", environ_prefix=None)
class BaseConfig(Configuration): BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SECRET_KEY = 'v)=y&*d5z$5*i9m-vsw_64s$o*)ith^r4ys6nnt&as1+j#f8se' DEBUG = True ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_extensions', 'users_app', 'raven.contrib.django.raven_compat', ] MIDDLEWARE = [ 'raven.contrib.django.raven_compat.middleware.Sentry404CatchMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'sci_blog.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'sci_blog.wsgi.application' DATABASES = values.DatabaseURLValue(environ_name='DB_URI') AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static') RAVEN_CONFIG = { 'dsn': values.Value(environ_name='RAVEN_DSN'), }
class Dev(Configuration): # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'y%ux@_^+#eahu3!^i2w71qtgidwpvs^o=w2*$=xy+2-y4r_!fw' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = values.BooleanValue(True) ALLOWED_HOSTS = values.ListValue([]) # Application definition INSTALLED_APPS = [ 'bookr_admin.apps.BookrAdminConfig', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', 'reviews', 'debug_toolbar', 'crispy_forms' ] MIDDLEWARE = [ 'debug_toolbar.middleware.DebugToolbarMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'bookr.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django.template.context_processors.media' ], }, }, ] WSGI_APPLICATION = 'bookr.wsgi.application' # Database # https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = values.DatabaseURLValue( 'sqlite:///{}/db.sqlite3'.format(BASE_DIR), environ_prefix='DJANGO') # Password validation # https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/dev/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/dev/howto/static-files/ STATIC_URL = '/static/' STATIC_ROOT = values.Value() STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] MEDIA_ROOT = values.Value(os.path.join(BASE_DIR, 'media')) MEDIA_URL = '/media/' INTERNAL_IPS = ['127.0.0.1'] CRISPY_TEMPLATE_PACK = 'bootstrap4'
# SECURITY # ------------------------------------------------------------------------------ SESSION_COOKIE_HTTPONLY = True CSRF_COOKIE_HTTPONLY = True SECURE_BROWSER_XSS_FILTER = True X_FRAME_OPTIONS = "DENY" # EMAIL # ------------------------------------------------------------------------------ EMAIL_BACKEND = env("DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.smtp.EmailBackend") EMAIL_TIMEOUT = 5 # ADMIN # ------------------------------------------------------------------------------ ADMIN_URL = values.Value("admin") # LOGGING # ------------------------------------------------------------------------------ LOGGING = { "version": 1, "disable_existing_loggers": False, "formatters": { "verbose": { "format": "%(levelname)s %(asctime)s %(module)s " "%(process)d %(thread)d %(message)s" } }, "handlers": { "console": {
class Base(Configuration): """ For more info about the `django-configurations` library, see https://django-configurations.readthedocs.io/en/latest/ """ DEBUG = False SECRET_KEY = values.Value() ALLOWED_HOSTS = [] SITE_URL = values.Value() SITE_ID = 1 INSTALLED_APPS = [ # django apps "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "django.contrib.sites", "django.contrib.sitemaps", "django.contrib.humanize", "django.contrib.postgres", # third-party apps "rest_framework", "storages", "taggit", "corsheaders", "ckeditor", "ckeditor_uploader", # project apps "buildings", "pages", "blog", ] MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "corsheaders.middleware.CorsMiddleware", "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] ROOT_URLCONF = "seismic_site.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "APP_DIRS": True, "DIRS": [os.path.join(BASE_DIR, "templates")], "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ] }, } ] WSGI_APPLICATION = "seismic_site.wsgi.application" # Database # https://docs.djangoproject.com/en/2.2/ref/settings/#databases DATABASES = values.DatabaseURLValue() # Password validation # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" # noqa }, { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator" # noqa }, { "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator" # noqa }, { "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator" # noqa }, ] # Internationalization # https://docs.djangoproject.com/en/2.2/topics/i18n/ LANGUAGE_CODE = values.Value(default="en-us") TIME_ZONE = "UTC" USE_I18N = True USE_L10N = True USE_TZ = True LANGUAGES = [("en", _("English")), ("ro", _("Romanian"))] # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.2/howto/static-files/ STATIC_URL = "/static/" STATIC_ROOT = os.path.join(BASE_DIR, "./public/static") # STATICFILES_DIRS = ( # os.path.join(BASE_DIR, 'static'), # ) STATICFILES_STORAGE = ( "whitenoise.storage.CompressedManifestStaticFilesStorage" ) MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, "./public/media") LOCALE_PATHS = [os.path.join(BASE_DIR, "./locale")] CKEDITOR_UPLOAD_PATH = "uploads/" REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. "DEFAULT_PERMISSION_CLASSES": [ "rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly" ] } TRIGRAM_SIMILARITY_THRESHOLD = 0.1
class Base(StyleguideMixin, DRFMixin, RichieCoursesConfigurationMixin, Configuration): """ This is the base configuration every configuration (aka environnement) should inherit from. It is recommended to configure third-party applications by creating a configuration mixins in ./configurations and compose the Base configuration with those mixins. It depends on an environment variable that SHOULD be defined: * DJANGO_SECRET_KEY You may also want to override default configuration by setting the following environment variables: * DJANGO_SENTRY_DSN * RICHIE_ES_HOST * DB_NAME * DB_HOST * DB_PASSWORD * DB_PORT * DB_USER """ DEBUG = False SITE_ID = 1 # Security ALLOWED_HOSTS = values.ListValue([]) SECRET_KEY = "ThisIsAnExampleKeyForDevPurposeOnly" # nosec # System check reference: # https://docs.djangoproject.com/en/3.1/ref/checks/#security SILENCED_SYSTEM_CHECKS = values.ListValue([ # Allow the X_FRAME_OPTIONS to be set to "SAMEORIGIN" "security.W019" ]) # The X_FRAME_OPTIONS value should be set to "SAMEORIGIN" to display # DjangoCMS frontend admin frames. Dockerflow raises a system check security # warning with this setting, one should add "security.W019" to the # SILENCED_SYSTEM_CHECKS setting (see above). X_FRAME_OPTIONS = "SAMEORIGIN" # Application definition ROOT_URLCONF = "funcampus.urls" WSGI_APPLICATION = "funcampus.wsgi.application" # Database DATABASES = { "default": { "ENGINE": values.Value( "django.db.backends.postgresql_psycopg2", environ_name="DB_ENGINE", environ_prefix=None, ), "NAME": values.Value("funcampus", environ_name="DB_NAME", environ_prefix=None), "USER": values.Value("funcampus", environ_name="DB_USER", environ_prefix=None), "PASSWORD": values.Value("pass", environ_name="DB_PASSWORD", environ_prefix=None), "HOST": values.Value("localhost", environ_name="DB_HOST", environ_prefix=None), "PORT": values.Value(5432, environ_name="DB_PORT", environ_prefix=None), } } MIGRATION_MODULES = {} # Static files (CSS, JavaScript, Images) STATIC_URL = "/static/" MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(DATA_DIR, "media") STATIC_ROOT = os.path.join(DATA_DIR, "static") # For static files, we want to use a backend that includes a hash in # the filename, that is calculated from the file content, so that browsers always # get the updated version of each file. STATICFILES_STORAGE = values.Value( "base.storage.CDNManifestStaticFilesStorage") # Login/registration related settings LOGIN_REDIRECT_URL = "/" LOGOUT_REDIRECT_URL = "/" # Internationalization TIME_ZONE = "Europe/Paris" USE_I18N = True USE_L10N = True USE_TZ = True LOCALE_PATHS = [os.path.join(BASE_DIR, "locale")] # Templates TEMPLATES = [{ "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [os.path.join(BASE_DIR, "templates")], "OPTIONS": { "context_processors": [ "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", "django.template.context_processors.i18n", "django.template.context_processors.debug", "django.template.context_processors.request", "django.template.context_processors.media", "django.template.context_processors.csrf", "django.template.context_processors.tz", "sekizai.context_processors.sekizai", "django.template.context_processors.static", "cms.context_processors.cms_settings", "richie.apps.core.context_processors.site_metas", ], "loaders": [ "django.template.loaders.filesystem.Loader", "django.template.loaders.app_directories.Loader", ], }, }] # Placeholders CMS_PLACEHOLDER_CONF_OVERRIDES = { "courses/cms/course_detail.html course_teaser": { "name": _("Teaser"), "plugins": ["LTIConsumerPlugin"], "limits": { "LTIConsumerPlugin": 1 }, }, } MIDDLEWARE = ( "richie.apps.core.cache.LimitBrowserCacheTTLHeaders", "cms.middleware.utils.ApphookReloadMiddleware", "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.locale.LocaleMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "dockerflow.django.middleware.DockerflowMiddleware", "cms.middleware.user.CurrentUserMiddleware", "cms.middleware.page.CurrentPageMiddleware", "cms.middleware.toolbar.ToolbarMiddleware", "cms.middleware.language.LanguageCookieMiddleware", "dj_pagination.middleware.PaginationMiddleware", ) # Django applications from the highest priority to the lowest INSTALLED_APPS = ( # funcampus stuff "base", # Richie stuff "richie.apps.demo", "richie.apps.search", "richie.apps.courses", "richie.apps.core", "richie.plugins.glimpse", "richie.plugins.html_sitemap", "richie.plugins.large_banner", "richie.plugins.lti_consumer", "richie.plugins.nesteditem", "richie.plugins.plain_text", "richie.plugins.section", "richie.plugins.simple_picture", "richie.plugins.simple_text_ckeditor", "richie", # Third party apps "dj_pagination", "dockerflow.django", "parler", "rest_framework", "storages", # Django-cms "djangocms_admin_style", "djangocms_googlemap", "djangocms_link", "djangocms_picture", "djangocms_text_ckeditor", "djangocms_video", "django_check_seo", "cms", "menus", "sekizai", "treebeard", "filer", "easy_thumbnails", # Django "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.admin", "django.contrib.sites", "django.contrib.sitemaps", "django.contrib.staticfiles", "django.contrib.messages", "django.contrib.humanize", ) # Search RICHIE_FILTERS_CONFIGURATION = [ ( "richie.apps.search.filter_definitions.IndexableHierarchicalFilterDefinition", { "human_name": _("Diplomas"), "is_autocompletable": True, "is_searchable": True, "min_doc_count": 0, "name": "diplomas", "position": 1, "reverse_id": "diplomas", "term": "categories", }, ), ( "richie.apps.search.filter_definitions.IndexableHierarchicalFilterDefinition", { "human_name": _("Domains and mentions"), "is_autocompletable": True, "is_searchable": True, "min_doc_count": 0, "name": "domains", "position": 2, "reverse_id": "domains", "term": "categories", }, ), ( "richie.apps.search.filter_definitions.IndexableHierarchicalFilterDefinition", { "human_name": _("Levels"), "is_autocompletable": True, "is_searchable": True, "min_doc_count": 0, "name": "levels", "position": 3, "reverse_id": "levels", "term": "categories", }, ), ( "richie.apps.search.filter_definitions.IndexableHierarchicalFilterDefinition", { "human_name": _("Skills"), "is_autocompletable": True, "is_searchable": True, "min_doc_count": 0, "name": "skills", "position": 4, "reverse_id": "skills", "term": "categories", }, ), ] # Languages # - Django LANGUAGE_CODE = "fr" # Careful! Languages should be ordered by priority, as this tuple is used to get # fallback/default languages throughout the app. # Use "en" as default as it is the language that is most likely to be spoken by any visitor # when their preferred language, whatever it is, is unavailable LANGUAGES = (("en", _("English")), ("fr", _("French"))) # CMS # Minimum enrollment count value that would be shown on course detail page RICHIE_MINIMUM_COURSE_RUNS_ENROLLMENT_COUNT = values.Value( environ_name="RICHIE_MINIMUM_COURSE_RUNS_ENROLLMENT_COUNT", environ_prefix=None, ) # - Django CMS CMS_LANGUAGES = { "default": { "public": True, "hide_untranslated": False, "redirect_on_fallback": True, "fallbacks": ["en", "fr"], }, 1: [ { "public": False, "code": "en", "hide_untranslated": False, "name": _("English"), "fallbacks": ["fr"], "redirect_on_fallback": True, }, { "public": True, "code": "fr", "hide_untranslated": False, "name": _("French"), "fallbacks": ["en"], "redirect_on_fallback": True, }, ], } # - Django Parler PARLER_LANGUAGES = CMS_LANGUAGES # Permisions # - Django CMS CMS_PERMISSION = True # - Django Filer FILER_ENABLE_PERMISSIONS = True FILER_IS_PUBLIC_DEFAULT = True # - Django Pagination PAGINATION_INVALID_PAGE_RAISES_404 = True PAGINATION_DEFAULT_WINDOW = 2 PAGINATION_DEFAULT_MARGIN = 1 # Logging LOGGING = { "version": 1, "disable_existing_loggers": True, "formatters": { "verbose": { "format": "%(levelname)s %(asctime)s %(module)s " "%(process)d %(thread)d %(message)s" } }, "handlers": { "console": { "level": "DEBUG", "class": "logging.StreamHandler", "formatter": "verbose", } }, "loggers": { "django.db.backends": { "level": "ERROR", "handlers": ["console"], "propagate": False, } }, } # Demo RICHIE_DEMO_SITE_DOMAIN = "localhost:8000" RICHIE_DEMO_FIXTURES_DIR = os.path.join(BASE_DIR, "base", "fixtures") # Elasticsearch RICHIE_ES_HOST = values.Value("elasticsearch", environ_name="RICHIE_ES_HOST", environ_prefix=None) RICHIE_ES_INDICES_PREFIX = values.Value( default="richie", environ_name="RICHIE_ES_INDICES_PREFIX", environ_prefix=None) RICHIE_ES_STATE_WEIGHTS = values.ListValue(None) # LTI Content RICHIE_LTI_PROVIDERS = { "marsha": { "oauth_consumer_key": values.Value( "InsecureOauthConsumerKey", environ_name="LTI_OAUTH_CONSUMER_KEY", environ_prefix=None, ), "shared_secret": values.Value( "InsecureSharedSecret", environ_name="LTI_SHARED_SECRET", environ_prefix=None, ), "base_url": values.Value( "https://marsha\.education/lti/videos/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}", # noqa environ_name="LTI_BASE_URL", environ_prefix=None, ), "display_name": "Marsha Video", "is_base_url_regex": True, "automatic_resizing": True, "inline_ratio": 0.5625, } } # Cache CACHES = values.DictValue({ "default": { "BACKEND": values.Value( "base.cache.RedisCacheWithFallback", environ_name="CACHE_DEFAULT_BACKEND", environ_prefix=None, ), "LOCATION": values.Value( "mymaster/redis-sentinel:26379,redis-sentinel:26379/0", environ_name="CACHE_DEFAULT_LOCATION", environ_prefix=None, ), "OPTIONS": values.DictValue( { "CLIENT_CLASS": "richie.apps.core.cache.SentinelClient", }, environ_name="CACHE_DEFAULT_OPTIONS", environ_prefix=None, ), "TIMEOUT": values.IntegerValue( 300, environ_name="CACHE_DEFAULT_TIMEOUT", environ_prefix=None, ), }, "memory_cache": { "BACKEND": values.Value( "django.core.cache.backends.locmem.LocMemCache", environ_name="CACHE_FALLBACK_BACKEND", environ_prefix=None, ), "LOCATION": values.Value( None, environ_name="CACHE_FALLBACK_LOCATION", environ_prefix=None, ), "OPTIONS": values.DictValue( {}, environ_name="CACHE_FALLBACK_OPTIONS", environ_prefix=None, ), }, }) # For more details about CMS_CACHE_DURATION, see : # http://docs.django-cms.org/en/latest/reference/configuration.html#cms-cache-durations CMS_CACHE_DURATIONS = values.DictValue({ "menus": 3600, "content": 86400, "permissions": 86400 }) MAX_BROWSER_CACHE_TTL = 600 # Sessions SESSION_ENGINE = values.Value("django.contrib.sessions.backends.cache") # Sentry SENTRY_DSN = values.Value(None, environ_name="SENTRY_DSN") # Admin # - Django CMS # Maximum children nodes to allow a parent to be unfoldable # in the page tree admin view CMS_PAGETREE_DESCENDANTS_LIMIT = 80 # - Django CMS Check SEO # Excludes all elements that are not related to the page content DJANGO_CHECK_SEO_EXCLUDE_CONTENT = ( "body > svg, #main-menu, .body-footer, .body-mentions") # pylint: disable=invalid-name @property def ENVIRONMENT(self): """Environment in which the application is launched.""" return self.__class__.__name__.lower() # pylint: disable=invalid-name @property def RELEASE(self): """ Return the release information. Delegate to the module function to enable easier testing. """ return get_release() # pylint: disable=invalid-name @property def CMS_CACHE_PREFIX(self): """ Set cache prefix specific to release so existing cache is invalidated for new deployments. """ return f"cms_{get_release():s}_" @classmethod def post_setup(cls): """Post setup configuration. This is the place where you can configure settings that require other settings to be loaded. """ super().post_setup() # The SENTRY_DSN setting should be available to activate sentry for an environment if cls.SENTRY_DSN is not None: sentry_sdk.init( dsn=cls.SENTRY_DSN, environment=cls.__name__.lower(), release=get_release(), integrations=[DjangoIntegration()], ) with sentry_sdk.configure_scope() as scope: scope.set_extra("application", "backend") # Customize DjangoCMS placeholders configuration cls.CMS_PLACEHOLDER_CONF = merge_dict( cls.CMS_PLACEHOLDER_CONF, cls.CMS_PLACEHOLDER_CONF_OVERRIDES)
class Common(Configuration): DEBUG = True TEMPLATE_DEBUG = DEBUG ENVIRONMENT = values.Value(environ_prefix=None, default='development') # Make this unique, and don't share it with anybody. # CONFIG.get('SECRET_KEY', 'PleaseDontTellEve') SECRET_KEY = values.SecretValue(environ_prefix=None) # Absolute filesystem path to the Django project directory: DJANGO_ROOT = dirname(abspath(__file__)) # Absolute filesystem path to the top-level project folder: SITE_ROOT = dirname(DJANGO_ROOT) # Site name: SITE_NAME = basename(DJANGO_ROOT) # Database Settings DATABASES = values.DatabaseURLValue( 'sqlite:///{}'.format(os.path.join(SITE_ROOT, 'db.sqlite3'))) # Get the latest head commit HEAD_COMMIT_ID = os.environ.get('HEAD_COMMIT_ID', 'BAD_HEAD_COMMIT')[:15] TEMPLATE_VISIBLE_SETTINGS = ('HEAD_COMMIT_ID',) ALLOWED_HOSTS = [ 'localhost', 'casp-staging.herokuapp.com', 'casp-production.herokuapp.com' ] ADMINS = ( ('Casp', '*****@*****.**'), ('Gerardo','*****@*****.**'), ('Francisco','[email protected] '), ) QUALITY_ASSURANCE = [ # '*****@*****.**' '*****@*****.**', '*****@*****.**', '*****@*****.**' ] MANAGERS = ADMINS # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # In a Windows environment this must be set to your system time zone. TIME_ZONE = 'America/Puerto_Rico' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-us' SITE_ID = 1 # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # If you set this to False, Django will not format dates, numbers and # calendars according to the current locale. USE_L10N = True # If you set this to False, Django will not use timezone-aware datetimes. USE_TZ = True # Absolute filesystem path to the directory that will hold user-uploaded files. # Example: "/home/media/media.lawrence.com/media/" MEDIA_ROOT = normpath(join(SITE_ROOT, 'media')) # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash. # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" MEDIA_URL = '/media/' # Absolute path to the directory static files should be collected to. # Don't put anything in this directory yourself; store your static files # in apps' "static/" subdirectories and in STATICFILES_DIRS. # Example: "/home/media/media.lawrence.com/static/" STATIC_ROOT = '' # URL prefix for static files. # Example: "http://media.lawrence.com/static/" STATIC_URL = '/static/' # Additional locations of static files STATICFILES_DIRS = ( # Put strings here, like "/home/html/static" or "C:/www/django/static". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. normpath(join(SITE_ROOT, 'static')), ) # List of finder classes that know how to find static files in # various locations. STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ) BRUNCH_DIR = join(SITE_ROOT, 'frontend') # Amazon s3 configuration # os.environ.get('AWS_ACCESS_KEY_ID', CONFIG['AWS_ACCESS_KEY_ID']) AWS_ACCESS_KEY_ID = values.Value(environ_prefix=None) # os.environ.get('AWS_SECRET_ACCESS_KEY', CONFIG['AWS_SECRET_ACCESS_KEY']) AWS_SECRET_ACCESS_KEY = values.Value(environ_prefix=None) # 'com-mlstudiopr-casp-app-staging', 'com-mlstudiopr-casp-app-production' AWS_STATIC_BUCKET_NAME = values.Value(environ_prefix=None) # 'com-mlstudiopr-casp-uploads-staging', 'com-mlstudiopr-casp-uploads-production' AWS_STORAGE_BUCKET_NAME = values.Value(environ_prefix=None) AWS_MEDIA_BUCKET_NAME = values.Value(environ_prefix=None) # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ) MIDDLEWARE_CLASSES = ( 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.transaction.TransactionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'reversion.middleware.RevisionMiddleware', ) ROOT_URLCONF = 'casp.urls' # Python dotted path to the WSGI application used by Django's runserver. WSGI_APPLICATION = 'casp.wsgi.application' TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. normpath(join(SITE_ROOT, 'templates')), ) TEMPLATE_CONTEXT_PROCESSORS = ( 'django.contrib.auth.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.tz', 'django.core.context_processors.request', 'django.contrib.messages.context_processors.messages', 'apps.utils.context_processors.settings' ) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', 'django.contrib.formtools', # Third-party 'django_extensions', 'gunicorn', 'south', 'bootstrapform', 'reversion', 'django_fsm', 'opbeat.contrib.django', 'bootstrap3', 'django_tables2', 'djrill', 'widget_tweaks', # 'django_bootstrap_calendar', # Local apps 'apps.django_popup_add', 'apps.cases', 'apps.contacts', 'apps.profiles', 'apps.events', 'apps.meetings', 'apps.notes', 'apps.bugs', 'apps.utils', 'apps.reports', 'apps.perms', 'apps.documents', ) # OPBEAT configuration ORGANIZATION_ID = values.Value(environ_prefix=None) APP_ID = values.Value(environ_prefix=None) SECRET_TOKEN = values.SecretValue(environ_prefix=None) OPBEAT = { 'ORGANIZATION_ID': ORGANIZATION_ID, 'APP_ID': APP_ID, 'SECRET_TOKEN': SECRET_TOKEN, } # User mode AUTH_USER_MODEL = 'profiles.CaspUser' # Auth LOGIN_REDIRECT_URL = 'case_list' # debug toolbar INTERNAL_IPS = ('127.0.0.1',) DEBUG_TOOLBAR_CONFIG = { 'INTERCEPT_REDIRECTS': False, } # Email setup # EMAIL_SUBJECT_PREFIX = '[{}] '.format(SITE_NAME.upper()) # EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # CONFIG.get('EMAIL_HOST') # EMAIL_HOST = values.Value(environ_prefix=None) # CONFIG.get('EMAIL_HOST_USER') # EMAIL_HOST_USER = values.Value(environ_prefix=None) # CONFIG.get('EMAIL_HOST_PASSWORD') # EMAIL_HOST_PASSWORD = values.Value(environ_prefix=None) # CONFIG.get('EMAIL_PORT') # EMAIL_PORT = values.Value(environ_prefix=None) # EMAIL_USE_TLS = True # Mandrill settings MANDRILL_API_KEY = values.SecretValue(environ_prefix=None) EMAIL_BACKEND = "djrill.mail.backends.djrill.DjrillBackend" DEFAULT_FROM_EMAIL = values.Value(environ_prefix=None) SERVER_EMAIL = values.Value(environ_prefix=None) # Celery settings BROKER_URL = values.Value(environ_prefix=None, default='redis://localhost//') #: Only add pickle to this list if your broker is secured #: from unwanted access (see userguide/security.html) CELERY_ACCEPT_CONTENT = ['json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' # Logging configuration adapted from: http://stackoverflow.com/a/5806903 LOG_LEVEL = 'DEBUG' if DEBUG else 'INFO' LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(pathname)s:%(lineno)d %(message)s' }, 'simple': { 'format': '%(levelname)s %(message)s' }, }, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'handlers': { 'null': { 'level': 'DEBUG', 'class': 'django.utils.log.NullHandler', }, 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'log_file': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join(SITE_ROOT, 'logs/django.log'), 'maxBytes': '16777216', 'formatter': 'verbose' }, 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler', 'include_html': True, } }, 'loggers': { 'django.request': { 'handlers': ['console'], 'level': 'ERROR', 'propagate': True, }, 'django.db.backends': { 'handlers': ['console'], 'level': 'INFO', 'propagate': True, }, 'apps': { 'handlers': ['console'], 'level': 'DEBUG', 'propagate': True, }, }, 'root': { 'handlers': ['console'], 'level': LOG_LEVEL }, } CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 'LOCATION': 'cache_table', } } CACHE_MIDDLEWARE_ALIAS = 'default' CACHE_MIDDLEWARE_SECONDS = 30 CACHE_MIDDLEWARE_KEY_PREFIX = ''