From d16bf5e6b0b6147c973bdcbb952e8d35d0f0f6b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 9 May 2020 11:49:05 +0200 Subject: [PATCH 01/10] Merge local and dev settings --- cof/settings/dev.py | 55 ------------------------------------------- cof/settings/local.py | 44 +++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 61 deletions(-) delete mode 100644 cof/settings/dev.py diff --git a/cof/settings/dev.py b/cof/settings/dev.py deleted file mode 100644 index d287eab8..00000000 --- a/cof/settings/dev.py +++ /dev/null @@ -1,55 +0,0 @@ -""" -Django development settings for the cof project. -The settings that are not listed here are imported from .common -""" - -import os - -from .common import * # NOQA -from .common import INSTALLED_APPS, MIDDLEWARE, TESTING - -EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" - -DEBUG = True - -if TESTING: - PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"] - -# As long as these apps are not ready for production, they are only available -# in development mode -INSTALLED_APPS += ["events", "bds", "clubs"] - - -# --- -# Apache static/media config -# --- - -STATIC_URL = "/static/" -STATIC_ROOT = "/srv/gestiocof/static/" - -MEDIA_ROOT = "/srv/gestiocof/media/" -MEDIA_URL = "/media/" - - -# --- -# Debug tool bar -# --- - - -def show_toolbar(request): - """ - On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar - car cela interfère avec l'utilisation de Vagrant. En effet, l'adresse de la - machine physique n'est pas forcément connue, et peut difficilement être - mise dans les INTERNAL_IPS. - """ - env_no_ddt = bool(os.environ.get("DJANGO_NO_DDT", None)) - return DEBUG and not env_no_ddt and not request.path.startswith("/admin/") - - -if not TESTING: - INSTALLED_APPS += ["debug_toolbar"] - - MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE - - DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": show_toolbar} diff --git a/cof/settings/local.py b/cof/settings/local.py index 06cdf4a0..789ec12b 100644 --- a/cof/settings/local.py +++ b/cof/settings/local.py @@ -1,14 +1,27 @@ """ -Django local settings for the cof project. +Django local development settings for the cof project. The settings that are not listed here are imported from .common """ import os -from .dev import * # NOQA -from .dev import BASE_DIR +from .common import * # NOQA +from .common import BASE_DIR, INSTALLED_APPS, MIDDLEWARE, TESTING + +EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" + +DEBUG = True + +if TESTING: + PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"] + +# As long as these apps are not ready for production, they are only available +# in development mode +INSTALLED_APPS += ["events", "bds", "clubs"] + +STATIC_URL = "/static/" +MEDIA_URL = os.path.join(BASE_DIR, "media") -# Use sqlite for local development DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", @@ -27,5 +40,24 @@ CHANNEL_LAYERS = { } } -# No need to run collectstatic -> unset STATIC_ROOT -STATIC_ROOT = None + +# --- +# Debug tool bar +# --- + + +def show_toolbar(request): + """ + On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar + car cela interfère avec l'utilisation de Vagrant. En effet, l'adresse de la + machine physique n'est pas forcément connue, et peut difficilement être + mise dans les INTERNAL_IPS. + """ + env_no_ddt = bool(os.environ.get("DJANGO_NO_DDT", None)) + return DEBUG and not env_no_ddt and not request.path.startswith("/admin/") + + +if not TESTING: + INSTALLED_APPS += ["debug_toolbar"] + MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE + DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": show_toolbar} From d464b69b2ea20e2c7448a1423a0a99ada4a4ed53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 9 May 2020 15:48:51 +0200 Subject: [PATCH 02/10] Split settings between COF / BDS / Local --- cof/settings/{prod.py => bds_prod.py} | 19 +-- cof/settings/cof_prod.py | 162 ++++++++++++++++++++++++++ cof/settings/common.py | 151 ++++++------------------ cof/settings/local.py | 33 ++++-- 4 files changed, 229 insertions(+), 136 deletions(-) rename cof/settings/{prod.py => bds_prod.py} (55%) create mode 100644 cof/settings/cof_prod.py diff --git a/cof/settings/prod.py b/cof/settings/bds_prod.py similarity index 55% rename from cof/settings/prod.py rename to cof/settings/bds_prod.py index 748abe73..d674a0a6 100644 --- a/cof/settings/prod.py +++ b/cof/settings/bds_prod.py @@ -6,14 +6,15 @@ The settings that are not listed here are imported from .common import os from .common import * # NOQA -from .common import BASE_DIR, INSTALLED_APPS, TESTING, import_secret +from .common import BASE_DIR, INSTALLED_APPS -DEBUG = False +# --- +# BDS-only Django settings +# --- -ALLOWED_HOSTS = ["cof.ens.fr", "www.cof.ens.fr", "dev.cof.ens.fr"] +ALLOWED_HOSTS = ["bds.ens.fr", "www.bds.ens.fr", "dev.cof.ens.fr"] -if TESTING: - INSTALLED_APPS += ["events", "clubs"] +INSTALLED_APPS += ["bds", "events", "clubs"] STATIC_ROOT = os.path.join( os.path.dirname(os.path.dirname(BASE_DIR)), "public", "gestion", "static" @@ -24,5 +25,9 @@ MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media") MEDIA_URL = "/gestion/media/" -RECAPTCHA_PUBLIC_KEY = import_secret("RECAPTCHA_PUBLIC_KEY") -RECAPTCHA_PRIVATE_KEY = import_secret("RECAPTCHA_PRIVATE_KEY") +# --- +# Auth-related stuff +# --- + +LOGIN_URL = "admin:login" +LOGIN_REDIRECT_URL = "bds:home" diff --git a/cof/settings/cof_prod.py b/cof/settings/cof_prod.py new file mode 100644 index 00000000..fe60af24 --- /dev/null +++ b/cof/settings/cof_prod.py @@ -0,0 +1,162 @@ +""" +Django development settings for the cof project. +The settings that are not listed here are imported from .common +""" + +import os + +from .common import * # NOQA +from .common import ( + AUTHENTICATION_BACKENDS, + BASE_DIR, + INSTALLED_APPS, + MIDDLEWARE, + TEMPLATES, + import_secret, +) + +# --- +# COF-specific secrets +# --- + +RECAPTCHA_PUBLIC_KEY = import_secret("RECAPTCHA_PUBLIC_KEY") +RECAPTCHA_PRIVATE_KEY = import_secret("RECAPTCHA_PRIVATE_KEY") +KFETOPEN_TOKEN = import_secret("KFETOPEN_TOKEN") + +# --- +# COF-only Django settings +# --- + +ALLOWED_HOSTS = ["cof.ens.fr", "www.cof.ens.fr", "dev.cof.ens.fr"] + +INSTALLED_APPS = ( + [ + "gestioncof", + # Must be before django admin + # https://github.com/infoportugal/wagtail-modeltranslation/issues/193 + "wagtail_modeltranslation", + "wagtail_modeltranslation.makemigrations", + "wagtail_modeltranslation.migrate", + "modeltranslation", + ] + + INSTALLED_APPS + + [ + "bda", + "petitscours", + "captcha", + "kfet", + "kfet.open", + "channels", + "custommail", + "djconfig", + "wagtail.contrib.forms", + "wagtail.contrib.redirects", + "wagtail.embeds", + "wagtail.sites", + "wagtail.users", + "wagtail.snippets", + "wagtail.documents", + "wagtail.images", + "wagtail.search", + "wagtail.admin", + "wagtail.core", + "wagtail.contrib.modeladmin", + "wagtail.contrib.routable_page", + "wagtailmenus", + "modelcluster", + "taggit", + "kfet.auth", + "kfet.cms", + "gestioncof.cms", + "django_js_reverse", + ] +) + +MIDDLEWARE = ( + ["corsheaders.middleware.CorsMiddleware"] + + MIDDLEWARE + + [ + "djconfig.middleware.DjConfigMiddleware", + "wagtail.core.middleware.SiteMiddleware", + "wagtail.contrib.redirects.middleware.RedirectMiddleware", + ] +) + +TEMPLATES[0]["OPTIONS"]["context_processors"] += [ + "wagtailmenus.context_processors.wagtailmenus", + "djconfig.context_processors.config", + "gestioncof.shared.context_processor", + "kfet.auth.context_processors.temporary_auth", + "kfet.context_processors.config", +] + +STATIC_ROOT = os.path.join( + os.path.dirname(os.path.dirname(BASE_DIR)), "public", "gestion", "static" +) + +STATIC_URL = "/gestion/static/" +MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media") +MEDIA_URL = "/gestion/media/" + +CORS_ORIGIN_WHITELIST = ("bda.ens.fr", "www.bda.ens.fr" "cof.ens.fr", "www.cof.ens.fr") + + +# --- +# Auth-related stuff +# --- + +AUTHENTICATION_BACKENDS += [ + "gestioncof.shared.COFCASBackend", + "kfet.auth.backends.GenericBackend", +] + +LOGIN_URL = "cof-login" +LOGIN_REDIRECT_URL = "home" + + +# --- +# reCAPTCHA settings +# https://github.com/praekelt/django-recaptcha +# +# Default settings authorize reCAPTCHA usage for local developement. +# Public and private keys are appended in the 'prod' module settings. +# --- + +NOCAPTCHA = True +RECAPTCHA_USE_SSL = True + + +# --- +# Wagtail settings +# --- + +WAGTAIL_SITE_NAME = "GestioCOF" +WAGTAIL_ENABLE_UPDATE_CHECK = False +TAGGIT_CASE_INSENSITIVE = True + + +# --- +# Django-js-reverse settings +# --- + +JS_REVERSE_JS_VAR_NAME = "django_urls" +# Quand on aura namespace les urls... +# JS_REVERSE_INCLUDE_ONLY_NAMESPACES = ['k-fet'] + + +# --- +# Mail config +# --- + +MAIL_DATA = { + "petits_cours": { + "FROM": "Le COF ", + "BCC": "archivescof@gmail.com", + "REPLYTO": "cof@ens.fr", + }, + "rappels": {"FROM": "Le BdA ", "REPLYTO": "Le BdA "}, + "revente": { + "FROM": "BdA-Revente ", + "REPLYTO": "BdA-Revente ", + }, +} diff --git a/cof/settings/common.py b/cof/settings/common.py index ecf464fe..0c34bf67 100644 --- a/cof/settings/common.py +++ b/cof/settings/common.py @@ -8,6 +8,10 @@ the local development server should be here. import os import sys +# --- +# Secrets +# --- + try: from . import secret except ImportError: @@ -42,19 +46,19 @@ REDIS_DB = import_secret("REDIS_DB") REDIS_HOST = import_secret("REDIS_HOST") REDIS_PORT = import_secret("REDIS_PORT") -KFETOPEN_TOKEN = import_secret("KFETOPEN_TOKEN") LDAP_SERVER_URL = import_secret("LDAP_SERVER_URL") +# --- +# Default Django settings +# --- + +DEBUG = False # False by default feels safer +TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -TESTING = sys.argv[1] == "test" - - -# Application definition INSTALLED_APPS = [ "shared", - "gestioncof", # Must be before 'django.contrib.admin'. # https://django-autocomplete-light.readthedocs.io/en/master/install.html "dal", @@ -64,51 +68,15 @@ INSTALLED_APPS = [ "django.contrib.sessions", "django.contrib.sites", "django.contrib.messages", - "cof.apps.IgnoreSrcStaticFilesConfig", - # Must be before django admin - # https://github.com/infoportugal/wagtail-modeltranslation/issues/193 - "wagtail_modeltranslation", - "wagtail_modeltranslation.makemigrations", - "wagtail_modeltranslation.migrate", - "modeltranslation", "django.contrib.admin", "django.contrib.admindocs", - "bda", - "petitscours", - "captcha", + "cof.apps.IgnoreSrcStaticFilesConfig", "django_cas_ng", "bootstrapform", - "kfet", - "kfet.open", - "channels", "widget_tweaks", - "custommail", - "djconfig", - "wagtail.contrib.forms", - "wagtail.contrib.redirects", - "wagtail.embeds", - "wagtail.sites", - "wagtail.users", - "wagtail.snippets", - "wagtail.documents", - "wagtail.images", - "wagtail.search", - "wagtail.admin", - "wagtail.core", - "wagtail.contrib.modeladmin", - "wagtail.contrib.routable_page", - "wagtailmenus", - "modelcluster", - "taggit", - "kfet.auth", - "kfet.cms", - "gestioncof.cms", - "django_js_reverse", ] - MIDDLEWARE = [ - "corsheaders.middleware.CorsMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", @@ -116,9 +84,6 @@ MIDDLEWARE = [ "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.security.SecurityMiddleware", - "djconfig.middleware.DjConfigMiddleware", - "wagtail.core.middleware.SiteMiddleware", - "wagtail.contrib.redirects.middleware.RedirectMiddleware", "django.middleware.locale.LocaleMiddleware", ] @@ -127,7 +92,6 @@ ROOT_URLCONF = "cof.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], "APP_DIRS": True, "OPTIONS": { "context_processors": [ @@ -138,11 +102,6 @@ TEMPLATES = [ "django.template.context_processors.i18n", "django.template.context_processors.media", "django.template.context_processors.static", - "wagtailmenus.context_processors.wagtailmenus", - "djconfig.context_processors.config", - "gestioncof.shared.context_processor", - "kfet.auth.context_processors.temporary_auth", - "kfet.context_processors.config", ] }, } @@ -158,43 +117,28 @@ DATABASES = { } } - -# Internationalization -# https://docs.djangoproject.com/en/1.8/topics/i18n/ - -LANGUAGE_CODE = "fr-fr" - -TIME_ZONE = "Europe/Paris" - -USE_I18N = True - -USE_L10N = True - -USE_TZ = True - -LANGUAGES = (("fr", "Français"), ("en", "English")) - -# Various additional settings SITE_ID = 1 -GRAPPELLI_ADMIN_HEADLINE = "GestioCOF" -GRAPPELLI_ADMIN_TITLE = 'GestioCOF' -MAIL_DATA = { - "petits_cours": { - "FROM": "Le COF ", - "BCC": "archivescof@gmail.com", - "REPLYTO": "cof@ens.fr", - }, - "rappels": {"FROM": "Le BdA ", "REPLYTO": "Le BdA "}, - "revente": { - "FROM": "BdA-Revente ", - "REPLYTO": "BdA-Revente ", - }, -} +# --- +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ +# --- -LOGIN_URL = "cof-login" -LOGIN_REDIRECT_URL = "home" +LANGUAGE_CODE = "fr-fr" +TIME_ZONE = "Europe/Paris" +USE_I18N = True +USE_L10N = True +USE_TZ = True +LANGUAGES = (("fr", "Français"), ("en", "English")) +FORMAT_MODULE_PATH = "cof.locale" + + +# --- +# Auth-related stuff +# --- + +AUTHENTICATION_BACKENDS = ["django.contrib.auth.backends.ModelBackend"] CAS_SERVER_URL = "https://cas.eleves.ens.fr/" CAS_VERSION = "2" @@ -203,37 +147,23 @@ CAS_IGNORE_REFERER = True CAS_REDIRECT_URL = "/" CAS_EMAIL_FORMAT = "%s@clipper.ens.fr" -AUTHENTICATION_BACKENDS = ( - "django.contrib.auth.backends.ModelBackend", - "gestioncof.shared.COFCASBackend", - "kfet.auth.backends.GenericBackend", -) - - -# reCAPTCHA settings -# https://github.com/praekelt/django-recaptcha -# -# Default settings authorize reCAPTCHA usage for local developement. -# Public and private keys are appended in the 'prod' module settings. - -NOCAPTCHA = True -RECAPTCHA_USE_SSL = True - -CORS_ORIGIN_WHITELIST = ("bda.ens.fr", "www.bda.ens.fr" "cof.ens.fr", "www.cof.ens.fr") - +# --- # Cache settings +# --- CACHES = { "default": { "BACKEND": "redis_cache.RedisCache", - "LOCATION": "redis://:{passwd}@{host}:{port}/db".format( + "LOCATION": "redis://:{passwd}@{host}:{port}/{db}".format( passwd=REDIS_PASSWD, host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB ), } } +# --- # Channels settings +# --- CHANNEL_LAYERS = { "default": { @@ -253,16 +183,3 @@ CHANNEL_LAYERS = { "ROUTING": "cof.routing.routing", } } - -FORMAT_MODULE_PATH = "cof.locale" - -# Wagtail settings - -WAGTAIL_SITE_NAME = "GestioCOF" -WAGTAIL_ENABLE_UPDATE_CHECK = False -TAGGIT_CASE_INSENSITIVE = True - -# Django-js-reverse settings -JS_REVERSE_JS_VAR_NAME = "django_urls" -# Quand on aura namespace les urls... -# JS_REVERSE_INCLUDE_ONLY_NAMESPACES = ['k-fet'] diff --git a/cof/settings/local.py b/cof/settings/local.py index 789ec12b..0ccb05dd 100644 --- a/cof/settings/local.py +++ b/cof/settings/local.py @@ -1,26 +1,35 @@ -""" -Django local development settings for the cof project. -The settings that are not listed here are imported from .common -""" +"""Django local development settings.""" import os -from .common import * # NOQA -from .common import BASE_DIR, INSTALLED_APPS, MIDDLEWARE, TESTING +from . import bds_prod +from .cof_prod import * # NOQA +from .cof_prod import BASE_DIR, INSTALLED_APPS, MIDDLEWARE, TESTING -EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" +# --- +# Merge COF and BDS configs +# --- + +for app in bds_prod.INSTALLED_APPS: + if app not in INSTALLED_APPS: + INSTALLED_APPS.append(app) + + +# --- +# Tweaks for debug/local development +# --- + +ALLOWED_HOSTS = None DEBUG = True +EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" if TESTING: PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"] -# As long as these apps are not ready for production, they are only available -# in development mode -INSTALLED_APPS += ["events", "bds", "clubs"] - STATIC_URL = "/static/" -MEDIA_URL = os.path.join(BASE_DIR, "media") +MEDIA_URL = "/media/" +MEDIA_ROOT = os.path.join(BASE_DIR, "media") DATABASES = { "default": { From 6a32a72c15eca15c6f7f246775f7e281eed7aef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 9 May 2020 16:21:40 +0200 Subject: [PATCH 03/10] One url file to rule them all, one url file to find them One url file to bring them all, and in the darkness bind them. --- bds/urls.py | 2 + cof/urls.py | 241 ++++++++++++++++++++++++++++------------------------ 2 files changed, 130 insertions(+), 113 deletions(-) create mode 100644 bds/urls.py diff --git a/bds/urls.py b/bds/urls.py new file mode 100644 index 00000000..e4487422 --- /dev/null +++ b/bds/urls.py @@ -0,0 +1,2 @@ +app_label = "bds" +urlpatterns = [] diff --git a/cof/urls.py b/cof/urls.py index 374c0f1a..12cf4f5a 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -8,129 +8,141 @@ from django.conf.urls.static import static from django.contrib import admin from django.contrib.auth import views as django_auth_views from django.urls import include, path -from django.views.decorators.cache import cache_page from django.views.generic.base import TemplateView from django_cas_ng import views as django_cas_views -from django_js_reverse.views import urls_js -from wagtail.admin import urls as wagtailadmin_urls -from wagtail.core import urls as wagtail_urls -from wagtail.documents import urls as wagtaildocs_urls - -from gestioncof import csv_views, views as gestioncof_views -from gestioncof.autocomplete import autocomplete -from gestioncof.urls import ( - calendar_patterns, - clubs_patterns, - events_patterns, - export_patterns, - surveys_patterns, -) admin.autodiscover() + urlpatterns = [ - # Page d'accueil - path("", gestioncof_views.HomeView.as_view(), name="home"), - # Le BdA - path("bda/", include("bda.urls")), - # Les exports - path("export/", include(export_patterns)), - # Les petits cours - path("petitcours/", include("petitscours.urls")), - # Les sondages - path("survey/", include(surveys_patterns)), - # Evenements - path("event/", include(events_patterns)), - # Calendrier - path("calendar/", include(calendar_patterns)), - # Clubs - path("clubs/", include(clubs_patterns)), - # Authentification - path( - "cof/denied", - TemplateView.as_view(template_name="cof-denied.html"), - name="cof-denied", - ), - path("cas/login", django_cas_views.LoginView.as_view(), name="cas_login_view"), - path("cas/logout", django_cas_views.LogoutView.as_view()), - path( - "outsider/login", gestioncof_views.LoginExtView.as_view(), name="ext_login_view" - ), - path( - "outsider/logout", django_auth_views.LogoutView.as_view(), {"next_page": "home"} - ), - path("login", gestioncof_views.login, name="cof-login"), - path("logout", gestioncof_views.logout, name="cof-logout"), - # Infos persos - path("profile", gestioncof_views.profile, name="profile"), - path( - "outsider/password-change", - django_auth_views.PasswordChangeView.as_view(), - name="password_change", - ), - path( - "outsider/password-change-done", - django_auth_views.PasswordChangeDoneView.as_view(), - name="password_change_done", - ), - # Inscription d'un nouveau membre - path("registration", gestioncof_views.registration, name="registration"), - path( - "registration/clipper//", - gestioncof_views.registration_form2, - name="clipper-registration", - ), - path( - "registration/user/", - gestioncof_views.registration_form2, - name="user-registration", - ), - path( - "registration/empty", - gestioncof_views.registration_form2, - name="empty-registration", - ), - # Autocompletion - path( - "autocomplete/registration", autocomplete, name="cof.registration.autocomplete" - ), - path( - "user/autocomplete", - gestioncof_views.user_autocomplete, - name="cof-user-autocomplete", - ), - # Interface admin - path("admin/logout/", gestioncof_views.logout), path("admin/doc/", include("django.contrib.admindocs.urls")), - path( - "admin///csv/", - csv_views.admin_list_export, - {"fields": ["username"]}, - ), path("admin/", admin.site.urls), - # Liens utiles du COF et du BdA - path("utile_cof", gestioncof_views.utile_cof, name="utile_cof"), - path("utile_bda", gestioncof_views.utile_bda, name="utile_bda"), - path("utile_bda/bda_diff", gestioncof_views.liste_bdadiff, name="ml_diffbda"), - path("utile_cof/diff_cof", gestioncof_views.liste_diffcof, name="ml_diffcof"), - path( - "utile_bda/bda_revente", - gestioncof_views.liste_bdarevente, - name="ml_bda_revente", - ), - path("k-fet/", include("kfet.urls")), - path("cms/", include(wagtailadmin_urls)), - path("documents/", include(wagtaildocs_urls)), - # djconfig - path("config", gestioncof_views.ConfigUpdate.as_view(), name="config.edit"), - # js-reverse - path("jsreverse/", urls_js, name="js_reverse"), ] +if "gestioncof" in settings.INSTALLED_APPS: + from gestioncof import csv_views, views as gestioncof_views + from gestioncof.autocomplete import autocomplete + from gestioncof.urls import ( + calendar_patterns, + clubs_patterns, + events_patterns, + export_patterns, + surveys_patterns, + ) + from django_js_reverse.views import urls_js + from wagtail.admin import urls as wagtailadmin_urls + from wagtail.documents import urls as wagtaildocs_urls + + # Also includes BdA, K-Fêt, etc. + urlpatterns += [ + path("admin/logout/", gestioncof_views.logout), + path( + "admin///csv/", + csv_views.admin_list_export, + {"fields": ["username"]}, + ), + # Page d'accueil + path("", gestioncof_views.HomeView.as_view(), name="home"), + # Le BdA + path("bda/", include("bda.urls")), + # Les exports + path("export/", include(export_patterns)), + # Les petits cours + path("petitcours/", include("petitscours.urls")), + # Les sondages + path("survey/", include(surveys_patterns)), + # Evenements + path("event/", include(events_patterns)), + # Calendrier + path("calendar/", include(calendar_patterns)), + # Clubs + path("clubs/", include(clubs_patterns)), + # Authentification + path( + "cof/denied", + TemplateView.as_view(template_name="cof-denied.html"), + name="cof-denied", + ), + path("cas/login", django_cas_views.LoginView.as_view(), name="cas_login_view"), + path("cas/logout", django_cas_views.LogoutView.as_view()), + path( + "outsider/login", + gestioncof_views.LoginExtView.as_view(), + name="ext_login_view", + ), + path( + "outsider/logout", + django_auth_views.LogoutView.as_view(), + {"next_page": "home"}, + ), + path("login", gestioncof_views.login, name="cof-login"), + path("logout", gestioncof_views.logout, name="cof-logout"), + # Infos persos + path("profile", gestioncof_views.profile, name="profile"), + path( + "outsider/password-change", + django_auth_views.PasswordChangeView.as_view(), + name="password_change", + ), + path( + "outsider/password-change-done", + django_auth_views.PasswordChangeDoneView.as_view(), + name="password_change_done", + ), + # Inscription d'un nouveau membre + path("registration", gestioncof_views.registration, name="registration"), + path( + "registration/clipper//", + gestioncof_views.registration_form2, + name="clipper-registration", + ), + path( + "registration/user/", + gestioncof_views.registration_form2, + name="user-registration", + ), + path( + "registration/empty", + gestioncof_views.registration_form2, + name="empty-registration", + ), + # Autocompletion + path( + "autocomplete/registration", + autocomplete, + name="cof.registration.autocomplete", + ), + path( + "user/autocomplete", + gestioncof_views.user_autocomplete, + name="cof-user-autocomplete", + ), + # Liens utiles du COF et du BdA + path("utile_cof", gestioncof_views.utile_cof, name="utile_cof"), + path("utile_bda", gestioncof_views.utile_bda, name="utile_bda"), + path("utile_bda/bda_diff", gestioncof_views.liste_bdadiff, name="ml_diffbda"), + path("utile_cof/diff_cof", gestioncof_views.liste_diffcof, name="ml_diffcof"), + path( + "utile_bda/bda_revente", + gestioncof_views.liste_bdarevente, + name="ml_bda_revente", + ), + path("k-fet/", include("kfet.urls")), + path("cms/", include(wagtailadmin_urls)), + path("documents/", include(wagtaildocs_urls)), + # djconfig + path("config", gestioncof_views.ConfigUpdate.as_view(), name="config.edit"), + # js-reverse + path("jsreverse/", urls_js, name="js_reverse"), + ] + +if "bds" in settings.INSTALLED_APPS: + urlpatterns.append(path("bds/", include("bds.urls"))) + if "events" in settings.INSTALLED_APPS: # The new event application is still in development # → for now it is namespaced below events_v2 - # → when the old events system is out, move this above in the others apps + # → rename this when the old events system is out urlpatterns += [path("event_v2/", include("events.urls"))] if "debug_toolbar" in settings.INSTALLED_APPS: @@ -144,6 +156,9 @@ if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # Wagtail for uncatched -urlpatterns += i18n_patterns( - path("", include(wagtail_urls)), prefix_default_language=False -) +if "wagtail.core" in settings.INSTALLED_APPS: + from wagtail.core import urls as wagtail_urls + + urlpatterns += i18n_patterns( + path("", include(wagtail_urls)), prefix_default_language=False + ) From 9a3914ece65667dcc9054e6af020bf2a4f2db5ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 9 May 2020 17:03:29 +0200 Subject: [PATCH 04/10] Add wsgi file --- cof/wsgi.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 cof/wsgi.py diff --git a/cof/wsgi.py b/cof/wsgi.py new file mode 100644 index 00000000..47285284 --- /dev/null +++ b/cof/wsgi.py @@ -0,0 +1,6 @@ +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings.bds_prod") +application = get_wsgi_application() From 7a52e841e61dc431702f14afd6cb9658f9061e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 9 May 2020 17:52:12 +0200 Subject: [PATCH 05/10] Use the new settings in gitlab-ci --- .gitlab-ci.yml | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 810c1132..36d123ff 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,6 @@ image: "python:3.7" variables: # GestioCOF settings - DJANGO_SETTINGS_MODULE: "cof.settings.prod" DBHOST: "postgres" REDIS_HOST: "redis" REDIS_PASSWD: "dummy" @@ -18,8 +17,7 @@ variables: # psql password authentication PGPASSWORD: $POSTGRES_PASSWORD -test: - stage: test +.test_template: before_script: - mkdir -p vendor/{pip,apt} - apt-get update -q && apt-get -o dir::cache::archives="vendor/apt" install -yqq postgresql-client libldap2-dev libsasl2-dev @@ -44,6 +42,19 @@ test: # Keep this disabled for now, as it may kill GitLab... # coverage: '/TOTAL.*\s(\d+\.\d+)\%$/' +coftest: + stage: test + extends: .test_template + variables: + DJANGO_SETTINGS_MODULE: "cof.settings.cof_prod" + +bdstest: + stage: test + extends: .test_template + variables: + DJANGO_SETTINGS_MODULE: "cof.settings.bds_prod" + + linters: stage: test before_script: @@ -60,8 +71,7 @@ linters: - vendor/ # Check whether there are some missing migrations. -migration_checks: - stage: test +.migration_checks_template: before_script: - mkdir -p vendor/{pip,apt} - apt-get update -q && apt-get -o dir::cache::archives="vendor/apt" install -yqq postgresql-client libldap2-dev libsasl2-dev @@ -76,3 +86,15 @@ migration_checks: key: migration_checks paths: - vendor/ + +cof_migration_checks: + stage: test + extends: .migration_checks_template + variables: + DJANGO_SETTINGS_MODULE: "cof.settings.cof_prod" + +bds_migration_checks: + stage: test + extends: .migration_checks_template + variables: + DJANGO_SETTINGS_MODULE: "cof.settings.bds_prod" From f26d3309738c991985d538d3723500e3c7346a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 14 May 2020 23:37:47 +0200 Subject: [PATCH 06/10] Fix settings.local.ALLOWED_HOSTS --- cof/settings/local.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cof/settings/local.py b/cof/settings/local.py index 0ccb05dd..bb06f006 100644 --- a/cof/settings/local.py +++ b/cof/settings/local.py @@ -19,7 +19,7 @@ for app in bds_prod.INSTALLED_APPS: # Tweaks for debug/local development # --- -ALLOWED_HOSTS = None +ALLOWED_HOSTS = [] DEBUG = True EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" From 25b603d6673fccfcbbf9dbb560034654dd1d27f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 14 May 2020 23:38:06 +0200 Subject: [PATCH 07/10] only run relevant tests in cof/bds CI --- .gitlab-ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 36d123ff..0c7c3c8f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,8 +27,6 @@ variables: - psql --username=$POSTGRES_USER --host=$DBHOST -c "DROP DATABASE IF EXISTS test_$POSTGRES_DB" - pip install --upgrade -r requirements-prod.txt coverage tblib - python --version - script: - - coverage run manage.py test --parallel after_script: - coverage report services: @@ -47,13 +45,16 @@ coftest: extends: .test_template variables: DJANGO_SETTINGS_MODULE: "cof.settings.cof_prod" + script: + - coverage run manage.py test gestioncof bda kfet petitscours shared --parallel bdstest: stage: test extends: .test_template variables: DJANGO_SETTINGS_MODULE: "cof.settings.bds_prod" - + script: + - coverage run manage.py test bds clubs events --parallel linters: stage: test From 3a34ab44621f43e7d1bf9e5834f25b6389e488d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Fri, 15 May 2020 20:37:37 +0200 Subject: [PATCH 08/10] Make events tests independent of LOGIN_URL --- events/tests/test_views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/events/tests/test_views.py b/events/tests/test_views.py index 3e13d8cd..b6251ae9 100644 --- a/events/tests/test_views.py +++ b/events/tests/test_views.py @@ -1,5 +1,6 @@ from unittest import mock +from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission from django.test import Client, TestCase @@ -59,9 +60,8 @@ class CSVExportAccessTest(MessagePatch, TestCase): def test_anonymous(self): client = Client() r = client.get(self.url) - self.assertRedirects( - r, "/login?next={}".format(self.url), fetch_redirect_response=False - ) + login_url = "{}?next={}".format(reverse(settings.LOGIN_URL), self.url) + self.assertRedirects(r, login_url, fetch_redirect_response=False) def test_unauthorised(self): client = Client() From eadfd1d3cd5b49c1c52cda6ad6cc800f085d273f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sun, 28 Jun 2020 18:58:45 +0200 Subject: [PATCH 09/10] Use cof.settings.local for migration checks --- .gitlab-ci.yml | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0c7c3c8f..3ef29950 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -72,12 +72,15 @@ linters: - vendor/ # Check whether there are some missing migrations. -.migration_checks_template: +migration_checks: + stage: test + variables: + DJANGO_SETTINGS_MODULE: "cof.settings.local" before_script: - mkdir -p vendor/{pip,apt} - apt-get update -q && apt-get -o dir::cache::archives="vendor/apt" install -yqq postgresql-client libldap2-dev libsasl2-dev - cp cof/settings/secret_example.py cof/settings/secret.py - - pip install --upgrade -r requirements-prod.txt + - pip install --upgrade -r requirements-devel.txt - python --version script: python manage.py makemigrations --dry-run --check services: @@ -87,15 +90,3 @@ linters: key: migration_checks paths: - vendor/ - -cof_migration_checks: - stage: test - extends: .migration_checks_template - variables: - DJANGO_SETTINGS_MODULE: "cof.settings.cof_prod" - -bds_migration_checks: - stage: test - extends: .migration_checks_template - variables: - DJANGO_SETTINGS_MODULE: "cof.settings.bds_prod" From f6458074b241dfa96e03641987359c494829bb5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sun, 28 Jun 2020 19:07:45 +0200 Subject: [PATCH 10/10] Better documentation for show_toobar --- cof/settings/local.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cof/settings/local.py b/cof/settings/local.py index bb06f006..b0ce5ae1 100644 --- a/cof/settings/local.py +++ b/cof/settings/local.py @@ -57,10 +57,15 @@ CHANNEL_LAYERS = { def show_toolbar(request): """ - On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar - car cela interfère avec l'utilisation de Vagrant. En effet, l'adresse de la - machine physique n'est pas forcément connue, et peut difficilement être - mise dans les INTERNAL_IPS. + On active la debug-toolbar en mode développement local sauf : + - dans l'admin où ça ne sert pas à grand chose; + - si la variable d'environnement DJANGO_NO_DDT est à 1 → ça permet de la désactiver + sans modifier ce fichier en exécutant `export DJANGO_NO_DDT=1` dans le terminal + qui lance `./manage.py runserver`. + + Autre side effect de cette fonction : on ne fait pas la vérification de INTERNAL_IPS + que ferait la debug-toolbar par défaut, ce qui la fait fonctionner aussi à + l'intérieur de Vagrant (comportement non testé depuis un moment…) """ env_no_ddt = bool(os.environ.get("DJANGO_NO_DDT", None)) return DEBUG and not env_no_ddt and not request.path.startswith("/admin/")