settings-sample.py 12 KB
Newer Older
1
'''
2 3 4 5 6 7 8 9 10
Django settings for manhattan_project project.

Generated by 'django-admin startproject' using Django 2.1.

For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
11
'''
12 13

import os
14
from datetime import date
15

16
from django.urls import reverse_lazy
17

18

19 20 21 22 23 24 25 26
# 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/2.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
27 28 29
SECRET_KEY = os.environ.get(
    'DJANGO_SECRET_KEY', 'xk6ujnt_zj7xlnt@c&$jc9f_=u3io5e!87imbqz4)=li*$tu%w'
)
30 31

# SECURITY WARNING: don't run with debug turned on in production!
32
DEBUG = os.environ.get('DEBUG', False) == 'True'
33

34
ALLOWED_HOSTS = []  # ['*']
35 36


37
DEFAULT_FROM_EMAIL = 'La Maestra <leocricia@manhattan.local>'
38
# Production value: 'django.core.mail.backends.smtp.EmailBackend'
39 40 41 42
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_HOST = 'smtp.manhattan.local'
EMAIL_HOST_USER = 'mls'
EMAIL_HOST_PASSWORD = 'plaff'
43 44 45 46 47
EMAIL_PORT = 587
EMAIL_USE_LOCALTIME = True
EMAIL_USE_TLS = True


48 49 50
# Application definition

INSTALLED_APPS = [
51 52 53 54 55 56
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
57
    # Local
58 59
    'indo.apps.IndoConfig',
    'accounts.apps.AccountsConfig',
60
    # 3rd Party
61 62 63 64
    'crispy_forms',  # https://github.com/django-crispy-forms/django-crispy-forms
    'django_summernote',  # https://github.com/summernote/django-summernote
    'django_tables2',  # https://github.com/jieter/django-tables2
    'social_django',  # https://github.com/python-social-auth/social-app-django
65 66 67
]

MIDDLEWARE = [
68 69 70 71 72 73 74
    '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',
75 76
]

77
ROOT_URLCONF = 'manhattan_project.urls'
78

79
SITE_URL = 'http://manhattan.local/'
80

81 82
TEMPLATES = [
    {
83 84 85 86 87 88 89 90
        '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',
91
                'django.template.context_processors.media',
92 93 94
                'django.contrib.messages.context_processors.messages',
                'social_django.context_processors.backends',
                'social_django.context_processors.login_redirect',
95
            ]
96
        },
97
    }
98 99
]

100
WSGI_APPLICATION = 'manhattan_project.wsgi.application'
101 102 103 104 105 106


# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

DATABASES = {
107 108 109 110 111 112 113
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # Database engine
        'NAME': os.environ.get('DB_NAME'),  # Database name
        'USER': os.environ.get('DB_USER'),  # Database user
        'PASSWORD': os.environ.get('DB_PASSWORD'),  # Database password
        'HOST': os.environ.get('DB_HOST'),  # Set to empty string for localhost.
        'PORT': '',  # Set to empty string for default.
114
        # Additional database options
115
        'OPTIONS': {'charset': 'utf8mb4'},  # Requires `innodb_default_row_format = dynamic`
116
    }
117 118 119 120 121 122 123
}


# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
124
    {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'},
125 126 127
    {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'},
    {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'},
    {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'},
128 129 130 131 132 133
]


# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/

134
LANGUAGE_CODE = 'es-es'
135

136
TIME_ZONE = 'Europe/Madrid'
137 138 139 140 141 142 143 144 145 146 147

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/

148 149 150 151
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
152

153 154 155 156
AUTH_USER_MODEL = 'accounts.CustomUser'
LOGIN_URL = f'{SITE_URL}login/saml/?idp=lord'
LOGIN_REDIRECT_URL = reverse_lazy('mis_proyectos', args=[date.today().year])
LOGOUT_REDIRECT_URL = 'home'
157 158


159
# ## SAML with Python Social Auth ## #
160 161
# https://python-social-auth.readthedocs.io/en/latest/backends/saml.html

162 163 164 165
AUTHENTICATION_BACKENDS = (
    'social_core.backends.saml.SAMLAuth',
    'django.contrib.auth.backends.ModelBackend',
)
166 167
# When using PostgreSQL,
# it’s recommended to use the built-in JSONB field to store the extracted extra_data.
168 169
# To enable it define the setting:
# SOCIAL_AUTH_POSTGRES_JSONFIELD = True
170
# Identifier of the SP entity (must be a URI)
171 172 173
SOCIAL_AUTH_SAML_SP_ENTITY_ID = 'https://manhattan.local/accounts/metadata'
SOCIAL_AUTH_SAML_SP_PUBLIC_CERT = '''Spam, ham and eggs'''
SOCIAL_AUTH_SAML_SP_PRIVATE_KEY = '''Spam, sausages and bacon'''
174
SOCIAL_AUTH_SAML_ORG_INFO = {
175 176 177 178 179 180 181 182 183
    'en-US': {
        'name': 'manhattan',
        'displayname': 'Proyectos de Innovación Docente',
        'url': 'http://manhattan.local',
    }
}
SOCIAL_AUTH_SAML_TECHNICAL_CONTACT = {
    'givenName': 'Quique',
    'emailAddress': 'quique@manhattan.local',
184 185
}
SOCIAL_AUTH_SAML_SUPPORT_CONTACT = {
186 187
    'givenName': 'Vicerrectorado de Política Académica',
    'emailAddress': 'innova.docen@manhattan.local',
188
}
189
# Si se cambia el backend de autenticación, actualizar clean() en InvitacionForm
190
SOCIAL_AUTH_SAML_ENABLED_IDPS = {
191 192 193 194 195 196 197 198 199 200
    'lord': {
        'entity_id': 'https://FIXME.idp.com/saml2/idp/metadata.php',
        'url': 'https://FIXME.idp.com/saml2/idp/SSOService.php',
        'slo_url': 'https://FIXME.idp.com/saml2/idp/SingleLogoutService.php',
        'x509cert': 'Lovely spam, wonderful spam',
        'attr_user_permanent_id': 'uid',
        'attr_full_name': 'cn',  # "urn:oid:2.5.4.3"
        'attr_first_name': 'givenName',  # "urn:oid:2.5.4.42"
        'attr_last_name': 'sn',  # "urn:oid:2.5.4.4"
        'attr_username': 'uid',  # "urn:oid:0.9.2342.19200300.100.1.1"
201 202 203 204
        # "attr_email": "email",            # "urn:oid:0.9.2342.19200300.100.1.3"
    }
}

205
SOCIAL_AUTH_PIPELINE = (
206 207 208 209 210 211
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.auth_allowed',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'social_core.pipeline.user.create_user',
212
    # Actualizar con los datos de Gestión de Identidades
213 214 215 216
    'accounts.pipeline.get_identidad',
    'social_core.pipeline.social_auth.associate_user',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
217 218
)

219
SOCIAL_AUTH_URL_NAMESPACE = 'social'
220 221

# CRISPY FORMS
222
CRISPY_TEMPLATE_PACK = 'bootstrap4'
223 224

# SUMMERNOTE
225 226
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
227

228
SUMMERNOTE_THEME = 'bs4'
229 230 231

SUMMERNOTE_CONFIG = {
    # Using SummernoteWidget - iframe mode, default
232
    'iframe': True,
233
    # You can put custom Summernote settings
234
    'summernote': {
235
        # As an example, using Summernote Air-mode
236
        # 'airMode': False,
237
        # Change editor size
238 239
        'width': '100%',
        'height': '480',
240
        # Use proper language setting automatically (default)
241
        'lang': None,
242 243 244 245 246 247
        # Or, set editor language/locale forcely
        # "lang": "ko-KR",
        # You can also add custom settings for external plugins
        # "print": {
        #     "stylesheetUrl": "/some_static_folder/printable.css",
        # },
248 249 250
        'codemirror': {
            'mode': 'htmlmixed',
            'lineNumbers': 'true',
251 252
            # You have to include theme file in 'css' or 'css_for_inplace'
            # before using it.
253
            'theme': 'monokai',
254
        },
255 256
        'placeholder': 'Introduzca sus comentarios',
        'toolbar': [
257
            # <https://summernote.org/deep-dive/#custom-toolbar-popover>
258 259 260 261 262 263
            ['style', ['style']],
            ['font', ['bold', 'italic', 'forecolor', 'superscript', 'subscript', 'clear']],
            ['para', ['ul', 'ol', 'paragraph']],
            ['table', ['table']],
            ['insert', ['link', 'picture']],
            ['view', ['fullscreen', 'codeview']],
264
        ],
265 266
        'codeviewFilter': True,
        'codeviewIframeFilter': True,
267 268
    },
    # Need authentication while uploading attachments.
269
    'attachment_require_authentication': True,
270
    # Set `upload_to` function for attachments.
271
    # 'attachment_upload_to': my_custom_upload_to_func(),
272
    # Set custom storage class for attachments.
273
    # 'attachment_storage_class': 'my.custom.storage.class.name',
274
    # Set custom model for attachments (default: 'django_summernote.Attachment')
275 276
    # must inherit 'django_summernote.AbstractAttachment'
    # 'attachment_model': 'my.custom.attachment.model',
277
    # You can disable attachment feature.
278
    # 'disable_attachment': False,
279
    # Set `True` to return attachment paths in absolute URIs.
280
    # 'attachment_absolute_uri': False,
281 282 283 284 285 286 287 288
    # test_func in summernote upload view.
    # (Allow upload images only when user passes the test)
    # https://docs.djangoproject.com/en/2.2/topics/auth/default/#django.contrib.auth.mixins.UserPassesTestMixin
    # ```
    # def example_test_func(request):
    #    return request.user.groups.filter(name='group_name').exists()
    # ```
    # 'test_func_upload_view': example_test_func,
289
    # You can add custom css/js for SummernoteWidget.
290 291 292
    # 'css': (),
    # 'js': (
    # ),
293 294
    # You can also add custom css/js for SummernoteInplaceWidget.
    # !!! Be sure to put {{ form.media }} in template before initiate summernote.
295 296 297 298
    # 'css_for_inplace': (
    # ),
    # 'js_for_inplace': (
    # ),
299
    # Codemirror as codeview
300 301
    # If any codemirror settings are defined,
    # it will include codemirror files automatically.
302
    'css': ('//cdnjs.cloudflare.com/ajax/libs/codemirror/5.29.0/theme/monokai.min.css',),
303 304 305
    # Lazy initialize
    # If you want to initialize summernote at the bottom of page, set this as True
    # and call `initSummernote()` on your page.
306
    'lazy': False,
307 308
    # To use external plugins,
    # Include them within `css` and `js`.
309 310 311 312
    # 'js': {
    #     '/some_static_folder/summernote-ext-print.js',
    #     '//somewhere_in_internet/summernote-plugin-name.js',
    # },
313
}
314

315 316
# BLEACH
ADDITIONAL_ALLOWED_TAGS = [
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
    'br',
    'del',
    'div',
    'dl',
    'dt',
    'dd',
    'em',
    'h1',
    'h2',
    'h3',
    'h4',
    'h5',
    'h6',
    'hr',
    'img',
    'ins',
    'p',
    'pre',
    'span',
    'strike',
    'sub',
    'sup',
    'table',
    'tbody',
    'td',
    'th',
    'thead',
    'tr',
    'u',
346 347
]
ALLOWED_ATTRIBUTES = {
348 349 350 351 352
    '*': ['class', 'id', 'style'],
    'a': ['alt', 'href', 'target', 'title'],
    'abbr': ['title'],
    'acronym': ['title'],
    'img': ['alt', 'src'],
353
}
354
ALLOWED_STYLES = ['background-color', 'color', 'text-align', 'width']
355
ALLOWED_PROTOCOLS = ['data', 'http', 'https', 'mailto']
356

357
X_FRAME_OPTIONS = 'SAMEORIGIN'  # Required by SummernoteWidget on Django 3.x
358 359

# WEB SERVICE DE GESTIÓN DE IDENTIDADES
360 361 362
WSDL_IDENTIDAD = os.environ.get('WSDL_IDENTIDAD')
USER_IDENTIDAD = os.environ.get('USER_IDENTIDAD')
PASS_IDENTIDAD = os.environ.get('PASS_IDENTIDAD')
363 364 365 366

WSDL_VINCULACIONES = os.environ.get('WSDL_VINCULACIONES')
USER_VINCULACIONES = os.environ.get('USER_VINCULACIONES')
PASS_VINCULACIONES = os.environ.get('PASS_VINCULACIONES')
367 368 369

# Titular actual del Vicerrectorado de Política Académica
VICERRECTOR = os.environ.get('VICERRECTOR')