settings.py 8.87 KB
Newer Older
1
import logging
2
import os
3
import time
4

BERJON Matthieu's avatar
BERJON Matthieu committed
5 6
from django.contrib.messages import constants as messages

7
from . import env
8 9 10 11

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
APPS_DIR = os.path.join(ROOT_DIR, 'allgo')

12

13 14
#FIXME: we should rather do these type conversions in config/env.py because
#       this is very error prone
15
def parse_bool(value):
BERJON Matthieu's avatar
BERJON Matthieu committed
16
    if value.lower() in (1, "true"):
17 18 19 20 21 22
        return True
    if value.lower() in (0, "false"):
        return False
    raise ValueError("invalid value %r (expected 'true' or 'false')" % value)


23 24 25 26 27
# load and possibly regenerate the secret key
def load_secret_key(path, expire):
    key = None
    try:
        mtime = os.path.getmtime(path)
BERJON Matthieu's avatar
BERJON Matthieu committed
28
        if mtime <= time.time() <= mtime + expire*86400:
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
            key = open(path).read()
        else:
            os.unlink(path)
    except FileNotFoundError:
        pass

    if key is None:
        logging.getLogger("allgo").info("regenerating a new secret key")
        key = os.urandom(128).hex()
        try:
            old_umask = os.umask(0o0077)
            with open(path, "w") as out:
                out.write(key)
        finally:
            os.umask(old_umask)

    assert len(key)>=256
    return key

48

49 50
# REQUIRED SETTINGS
# ------------------------------------------------------------------------------
51 52

SECRET_KEY = load_secret_key(env.ALLGO_SECRET_KEY_PATH, int(env.ALLGO_SECRET_KEY_DAYS))
53 54 55 56


# GENERAL
# ------------------------------------------------------------------------------
57
DEBUG = parse_bool(env.ALLGO_DEBUG)
58
ALLOWED_HOSTS = env.ALLGO_ALLOWED_HOSTS.split(",")
59 60 61 62 63 64

# Allgo is expected to be hosted behind a reverse proxy, thus we trust the
# X-Forwarded-Host header set by the proxy
USE_X_FORWARDED_HOST = True


65 66
TIME_ZONE = 'UTC'
LANGUAGE_CODE = 'en-us'
67
SITE_ID = env.ALLGO_SITE_ID
68 69 70 71 72 73 74 75 76
USE_I18N = True
USE_L10N = True
USE_TZ = True


# DATABASES
# ------------------------------------------------------------------------------
DATABASES = {
        'default': {
77 78 79 80 81
            'ENGINE':   env.ALLGO_DATABASE_ENGINE,
            'NAME':     env.ALLGO_DATABASE_NAME,
            'USER':     env.ALLGO_DATABASE_USER,
            'PASSWORD': env.ALLGO_DATABASE_PASSWORD,
            'HOST':     env.ALLGO_DATABASE_HOST,
82 83
            'OPTIONS': {'sql_mode': env.ALLGO_DATABASE_MODE},
            'TEST': {
84
                'NAME': 'allgo_test',
85 86 87 88
                'CHARSET': 'utf8',
                'COLLATE': 'utf8_general_ci',
            },
        },
89 90 91 92 93 94 95 96
}
DATABASES['default']['ATOMIC_REQUESTS'] = True


# URLS
# ------------------------------------------------------------------------------
ROOT_URLCONF = 'config.urls'
WSGI_APPLICATION = 'config.wsgi.application'
BERJON Matthieu's avatar
BERJON Matthieu committed
97
APPEND_SLASH = False
98 99 100

# APPS
# ------------------------------------------------------------------------------
101

102 103 104
DJANGO_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
105
    'django.contrib.sites',
106 107 108 109
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
110
    'django.contrib.humanize',
111
]
112 113 114 115
THIRD_PARTY_APPS = [
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
BERJON Matthieu's avatar
BERJON Matthieu committed
116
    'allauth.socialaccount.providers.gitlab',
BERJON Matthieu's avatar
BERJON Matthieu committed
117
    'taggit',
118
    'django_extensions',
119
]
120
LOCAL_APPS = [
121
    'main',
122
    'api.v1',
CAMPION Sebastien's avatar
CAMPION Sebastien committed
123
    'jwt'
124 125
]

126 127
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS + list(
        filter(bool, env.ALLGO_ADDITIONAL_APPS.split(",")))
128 129 130 131 132 133 134 135 136 137 138 139


# MIGRATIONS
# ------------------------------------------------------------------------------
MIGRATION_MODULES = {
        'sites': 'django.contrib.sites.migrations'
}


# AUTHENTIFICATION
# ------------------------------------------------------------------------------
AUTHENTIFICATION_BACKENDS = [
140
        'allauth.account.auth_backends.AuthenticationBackend',
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
]
LOGIN_REDIRECT_URL = 'main:home'
LOGOUT_REDIRECT_URL = 'main:home'


# PASSWORDS
# ------------------------------------------------------------------------------
PASSWORD_HASHERS = [
        'django.contrib.auth.hashers.PBKDF2PasswordHasher',
        'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
        'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
        'django.contrib.auth.hashers.BCryptPasswordHasher',
]
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',
        },
]


# MIDDLEWARE
# ------------------------------------------------------------------------------
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',
]


# STATIC
# ------------------------------------------------------------------------------
185
STATIC_ROOT = env.ALLGO_STATIC_PATH
186 187 188 189 190 191 192 193 194 195 196 197
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(APPS_DIR, 'static'),
]
STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]


# MEDIA
# ------------------------------------------------------------------------------
198
MEDIA_ROOT = env.ALLGO_MEDIA_PATH
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
MEDIA_URL = '/media/'


# TEMPLATES
# ------------------------------------------------------------------------------
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(APPS_DIR, 'templates'),
        ],
        'OPTIONS': {
            'debug': DEBUG,
            'loaders': [
                'django.template.loaders.filesystem.Loader',
                'django.template.loaders.app_directories.Loader',
            ],
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.template.context_processors.media',
                'django.template.context_processors.i18n',
                'django.template.context_processors.static',
                'django.template.context_processors.tz',
                'django.contrib.messages.context_processors.messages',
BAIRE Anthony's avatar
BAIRE Anthony committed
225
                'main.context_processors.global_context',
226 227 228 229 230 231 232 233
            ],
        },
    },
]


# EMAIL
# ------------------------------------------------------------------------------
BERJON Matthieu's avatar
BERJON Matthieu committed
234 235 236 237 238
EMAIL_BACKEND = env.ALLGO_EMAIL_BACKEND
DEFAULT_FROM_EMAIL = env.ALLGO_EMAIL_FROM
EMAIL_HOST = env.ALLGO_EMAIL_HOST
EMAIL_PORT = env.ALLGO_EMAIL_PORT
EMAIL_HOST_USER = env.ALLGO_EMAIL_USER
239
EMAIL_HOST_PASSWORD = env.ALLGO_EMAIL_PASSWORD
BERJON Matthieu's avatar
BERJON Matthieu committed
240
EMAIL_USE_TLS = parse_bool(env.ALLGO_EMAIL_TLS)
241 242 243 244 245 246 247 248 249


# ADMIN
# ------------------------------------------------------------------------------
ADMIN_URL = r'^admin/'
ADMINS = [
    ("""Matthieu Berjon""", 'matthieu.berjon@inria.fr'),
]
MANAGERS = ADMINS
250 251 252 253 254 255 256 257 258

# Allauth
# ------------------------------------------------------------------------------
ACCOUNT_AUTHENTICATION_METHOD = 'username_email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_SUBJECT_PREFIX = '[A||go] '
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_ADAPTER = 'allgo.main.adapter.AccountAdapter'
BERJON Matthieu's avatar
BERJON Matthieu committed
259 260 261 262
ACCOUNT_PRESERVE_USERNAME_CASING = False  # force lowercase on username

SOCIALACCOUNT_PROVIDERS = {
    'gitlab': {
263
        'GITLAB_URL': env.ALLGO_AUTH_GITLAB_URL,
BERJON Matthieu's avatar
BERJON Matthieu committed
264 265 266
        'SCOPE': ['read_user'],
    },
}
267

268
ALLOWED_DEVELOPER_DOMAINS = env.ALLGO_ALLOWED_DEVELOPER_DOMAINS.split(",")
269

BERJON Matthieu's avatar
BERJON Matthieu committed
270 271
# Logging
# ------------------------------------------------------------------------------
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
            'style': '{',
        },
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
    },
    'loggers': {
        'allgo': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        },
BAIRE Anthony's avatar
BAIRE Anthony committed
296 297 298 299
        'jwt': {
            'handlers': ['console'],
            'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
        }
300
    },
301
}
BERJON Matthieu's avatar
BERJON Matthieu committed
302

BERJON Matthieu's avatar
BERJON Matthieu committed
303 304
# DATASTORE
# ------------------------------------------------------------------------------
BERJON Matthieu's avatar
BERJON Matthieu committed
305
DATASTORE = os.environ.get('ALLGO_DATASTORE', default='/vol/rw/datastore')
BERJON Matthieu's avatar
BERJON Matthieu committed
306 307 308 309

MESSAGE_TAGS = {
    messages.ERROR: 'danger'
}
310