diff --git a/.env.develop.example b/.env.develop.example new file mode 100644 index 0000000..801b9f3 --- /dev/null +++ b/.env.develop.example @@ -0,0 +1,5 @@ +ENVIRONMENT = develop +DEBUG = yes +SECRET_KEY = not-a-secret-key +DATABASE_ENGINE = sqlite3 +EMAIL_BACKEND = console diff --git a/.env.production.example b/.env.production.example new file mode 100644 index 0000000..e43c74b --- /dev/null +++ b/.env.production.example @@ -0,0 +1,13 @@ +ENVIRONMENT = production +DEBUG = no +SECRET_KEY = +HOST = https://foerderung.wikimedia.de +DATABASE_ENGINE = mysql +DATABASE_PASSWORD = +EMAIL_BACKEND = smtp +EMAIL_HOST_USER = +EMAIL_HOST_PASSWORD = +OAUTH_ENABLED = yes +OAUTH_CLIENT_NAME = +OAUTH_CLIENT_ID = +OAUTH_CLIENT_SECRET = diff --git a/.gitignore b/.gitignore index 502cdf4..c8ad5bd 100755 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # secret passwords and so /secrets.json /staticfiles -foerderbarometer/settings.py /nohup.out /logfile *~ diff --git a/README.md b/README.md index 164ba53..49027d4 100755 --- a/README.md +++ b/README.md @@ -4,7 +4,10 @@ purpose: gather data from intern(WMDE) and extern(volunteers) forms to create a ## installation and development setup - ln -sr foerderbarometer/settings_development.py foerderbarometer/settings.py + cp .env.develop.example .env + +To use a MariaDB change `DATABASE_ENGINE` in .env to `mysql` and amend `DATABASE_*` variables according to your setup. +For further information see the production setup below. build the database with @@ -65,16 +68,26 @@ run some tests with ## production setup - ln -sr foerderbarometer/settings_production.py foerderbarometer/settings.py + cp .env.production.example .env -edit /secrets.json to contain something similar to +edit .env and fill in the missing secrets - { - "DATABASE_PASSWORD": "THIS IS TOP SECRET!", - "SECRET_KEY": "THIS IS ANOTHER SECRET!" - } + SECRET_KEY + DATABASE_PASSWORD + EMAIL_HOST_USER + EMAIL_HOST_PASSWORD + OAUTH_CLIENT_NAME + OAUTH_CLIENT_ID + OAUTH_CLIENT_SECRET -edit foerderbarometer/settings_production.py according to your database setup (tested with MariaDB 10.0.36) +amend database variables to .env according to your database setup (tested with MariaDB 10.0.36), e.g. + + DATABASE_NAME + DATABASE_USER + DATABASE_HOST + DATABASE_PORT + +for a full set of all possible env vars have a look at foerderbarometer/settings.py run the following commands: diff --git a/foerderbarometer/settings.py b/foerderbarometer/settings.py new file mode 100644 index 0000000..4354ec7 --- /dev/null +++ b/foerderbarometer/settings.py @@ -0,0 +1,164 @@ +import os + +from pathlib import Path + +from dotenv import load_dotenv + +from input.utils.settings import env, password_validators + +BASE_DIR = Path(__file__).parents[1] + +load_dotenv(BASE_DIR / '.env') + +DEBUG = env('DEBUG', False) + +SECRET_KEY = env('SECRET_KEY') + +ALLOWED_HOSTS = ['*'] + +HOST = env('HOST', 'http://localhost:8000') + +INSTALLED_APPS = [ + 'input.apps.InputConfig', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'formtools', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + '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 = 'foerderbarometer.urls' + +DJANGO_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', + ], + }, +} + +TEMPLATES = [DJANGO_TEMPLATES] + +WSGI_APPLICATION = 'foerderbarometer.wsgi.application' + +DATABASE_ENGINE = env('DATABASE_ENGINE', 'mysql') + +DATABASE_SQLITE = { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', +} + +DATABASE_MYSQL = { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': env('DATABASE_NAME', 'fdb'), + 'USER': env('DATABASE_USER', 'fdb'), + 'PASSWORD': env('DATABASE_PASSWORD'), + 'HOST': env('DATABASE_HOST', 'localhost'), + 'PORT': env('DATABASE_PORT', 3306), + 'OPTIONS': { + 'charset' : 'utf8', + 'use_unicode' : True, + 'init_command': 'SET ' + 'storage_engine=INNODB,' + 'character_set_connection=utf8,' + 'collation_connection=utf8_bin' + }, + 'TEST_CHARSET': 'utf8', + 'TEST_COLLATION': 'utf8_general_ci', +} + +if DATABASE_ENGINE == 'mysql': + DATABASE_DEFAULT = DATABASE_MYSQL +else: + DATABASE_DEFAULT = DATABASE_SQLITE + +DATABASES = { + 'default': DATABASE_DEFAULT, +} + +EMAIL_BACKEND = env('EMAIL_BACKEND', 'console') + +if EMAIL_BACKEND == 'smtp': + EMAIL_HOST = env('EMAIL_HOST', 'email.wikimedia.de') + EMAIL_PORT = env('EMAIL_PORT', 587) + EMAIL_USE_TLS = env('EMAIL_USE_TLS', True) + EMAIL_HOST_USER = env('EMAIL_HOST_USER') + EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD') + +EMAIL_BACKEND = f'django.core.mail.backends.{EMAIL_BACKEND}.EmailBackend' +EMAIL_URL_PREFIX = env('EMAIL_URL_PREFIX', HOST) + +AUTH_PASSWORD_VALIDATORS = password_validators( + 'UserAttributeSimilarityValidator', + 'MinimumLengthValidator', + 'CommonPasswordValidator', + 'NumericPasswordValidator', +) + +USE_I18N = True +USE_L10N = True +LANGUAGE_CODE = env('LANGUAGE_CODE', 'en-us') + +USE_TZ = True +TIME_ZONE = env('TIME_ZONE', 'UTC') + +STATIC_ROOT = BASE_DIR / 'staticfiles' +STATIC_URL = '/static/' + +if OAUTH_ENABLED := env('OAUTH_ENABLED', not DEBUG): + MIDDLEWARE += ['input.middleware.oauth.OAuthMiddleware'] + +OAUTH_CLIENT_NAME = env('OAUTH_CLIENT_NAME') + +OAUTH_CLIENT = { + 'client_id': env('OAUTH_CLIENT_ID'), + 'client_secret': env('OAUTH_CLIENT_SECRET'), + 'access_token_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/access_token', + 'authorize_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/authorize', + 'api_base_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/resource', + 'redirect_uri': env('OAUTH_REDIRECT_URI', f'{HOST}/oauth/callback'), + 'client_kwargs': { + 'scope': 'basic', + 'token_placement': 'header' + }, + 'userinfo_endpoint': 'resource/profile', +} + +OAUTH_URL_WHITELISTS = ['/admin'] + +OAUTH_COOKIE_SESSION_ID = 'sso_session_id' + +IF_EMAIL = env('IF_EMAIL', 'community@wikimedia.de') + +SURVEY_EMAIL = env('SURVEY_EMAIL', 'sandro.halank@wikimedia.de') +SURVEY_PREFIX = env('SURVEY_PREFIX', 'https://wikimedia.sslsurvey.de/Foerderbarometer/?') + +DATAPROTECTION = 'https://www.wikimedia.de/datenschutz/#datenerfassung' +FOERDERRICHTLINIEN = 'https://de.wikipedia.org/wiki/Wikipedia:Wikimedia_Deutschland/Richtlinie_zur_Förderung_der_Communitys' + +NUTZUNGSBEDINGUNGEN = 'static/input/nutzungsbedingungen.html' +NUTZUNGSBEDINGUNGEN_EMAIL_SERVICE = 'static/input/nutzungsbedingungen-mail.pdf' +NUTZUNGSBEDINGUNGEN_MAILINGLISTEN = 'static/input/nutzungsbedingungen-mailinglisten.pdf' +NUTZUNGSBEDINGUNGEN_LITERATURSTIPENDIUM = 'static/input/nutzungsbedingungen-literaturstipendium.pdf' +NUTZUNGSBEDINGUNGEN_OTRS = 'static/input/2025_Nutzungsvereinbarung_OTRS.docx.pdf' +NUTZUNGSBEDINGUNGEN_VISITENKARTEN = 'static/input/nutzungsbedingungen-visitenkarten.pdf' diff --git a/foerderbarometer/settings.py.example b/foerderbarometer/settings.py.example deleted file mode 100755 index c668c9f..0000000 --- a/foerderbarometer/settings.py.example +++ /dev/null @@ -1,203 +0,0 @@ -""" -Django settings for foerderbarometer project. - -Generated by 'django-admin startproject' using Django 3.1.1. - -For more information on this file, see -https://docs.djangoproject.com/en/3.1/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.1/ref/settings/ -""" - -import json -import os -from pathlib import Path - -from django.core.exceptions import ImproperlyConfigured - -# prefix for urls in mails -URLPREFIX = 'https://fdb-devel.wikimedia.de' - - -# mails in development go to stdout -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' - -CSRF_TRUSTED_ORIGINS = ['https://fdb-devel.wikimedia.de'] - -# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' - -EMAIL_HOST = 'xemail.wikimedia.de' -EMAIL_PORT = '587' -EMAIL_USE_TLS = True -#EMAIL_HOST_USER = get_secret('EMAIL_HOST_USER') -#EMAIL_HOST_PASSWORD = get_secret('EMAIL_HOST_PASSWORD') - - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - -# get secrets -with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file: - secrets = json.load(secrets_file) - -def get_secret(setting, secrets=secrets): - """Get secret setting or fail with ImproperlyConfigured""" - try: - return secrets[setting] - except KeyError: - raise ImproperlyConfigured("Set the {} setting".format(setting)) - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = get_secret('SECRET_KEY') - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -STATIC_ROOT = BASE_DIR / 'staticfiles' - -ALLOWED_HOSTS = ['*'] - - -# Application definition - -INSTALLED_APPS = [ - 'input.apps.InputConfig', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'formtools', -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - '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', - 'input.middleware.oauth.OAuthMiddleware' -] - -ROOT_URLCONF = 'foerderbarometer.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 = 'foerderbarometer.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/3.1/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'fdbdevel', - 'USER': 'fdbdevel', - 'PASSWORD': get_secret('DATABASE_PASSWORD'), - 'HOST': '10.0.6.224', # Or an IP Address that your database is hosted on - # 'PORT': '3306', - #optional: - 'OPTIONS': { - 'charset' : 'utf8', - 'use_unicode' : True, - 'init_command': 'SET ' - 'storage_engine=INNODB,' - 'character_set_connection=utf8,' - 'collation_connection=utf8_bin' - #'sql_mode=STRICT_TRANS_TABLES,' # see note below - #'SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', - }, - 'TEST_CHARSET': 'utf8', - 'TEST_COLLATION': 'utf8_general_ci', - } -} - -# Password validation -# https://docs.djangoproject.com/en/3.1/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/3.1/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/3.1/howto/static-files/ - -STATIC_URL = '/static/' - -# needed since django 3.2 -DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' - - -# OAuth Settings -OAUTH_URL_WHITELISTS = ['/admin'] - -OAUTH_CLIENT_NAME = '' -OAUTH_CLIENT_NAME = get_secret('OAUTH_CLIENT_NAME') - - -OAUTH_CLIENT = { - 'client_id': get_secret('OAUTH_CLIENT_ID'), - 'client_secret': get_secret('OAUTH_CLIENT_SECRET'), - 'access_token_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/access_token', - 'authorize_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/authorize', - 'api_base_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/resource', - 'redirect_uri': 'https://fdb-devel.wikimedia.de/oauth/callback', - 'client_kwargs': { - 'scope': 'basic', - 'token_placement': 'header' - }, - 'userinfo_endpoint': 'resource/profile', -} - -OAUTH_COOKIE_SESSION_ID = 'sso_session_id' diff --git a/foerderbarometer/settings.py_old b/foerderbarometer/settings.py_old deleted file mode 100755 index 3b3ff79..0000000 --- a/foerderbarometer/settings.py_old +++ /dev/null @@ -1,151 +0,0 @@ -""" -Django settings for foerderbarometer project. - -Generated by 'django-admin startproject' using Django 3.1.1. - -For more information on this file, see -https://docs.djangoproject.com/en/3.1/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.1/ref/settings/ -""" - -import json -import os -from pathlib import Path - -from django.core.exceptions import ImproperlyConfigured - -# prefix for urls in mails -URLPREFIX = 'http://localhost:8000' - -# mails in development go to stdout -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - -# get secrets -with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file: - secrets = json.load(secrets_file) - -def get_secret(setting, secrets=secrets): - """Get secret setting or fail with ImproperlyConfigured""" - try: - return secrets[setting] - except KeyError: - raise ImproperlyConfigured("Set the {} setting".format(setting)) - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '*&7p9#_n$@^%0z49s+7jpy@+j1rw_hqh05knyd6y2*!0)r&b6h' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -STATIC_ROOT = BASE_DIR / 'staticfiles' - -ALLOWED_HOSTS = ['*'] - - -# Application definition - -INSTALLED_APPS = [ - 'input.apps.InputConfig', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'formtools', -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - '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 = 'foerderbarometer.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 = 'foerderbarometer.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/3.1/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', - 'PASSWORD': get_secret('DATABASE_PASSWORD') - } -} - - -# Password validation -# https://docs.djangoproject.com/en/3.1/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/3.1/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/3.1/howto/static-files/ - -STATIC_URL = '/static/' - -# needed since django 3.2 -DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' diff --git a/foerderbarometer/settings_development.py b/foerderbarometer/settings_development.py deleted file mode 100755 index 15c0f3d..0000000 --- a/foerderbarometer/settings_development.py +++ /dev/null @@ -1,158 +0,0 @@ -""" -Django settings for foerderbarometer project. - -Generated by 'django-admin startproject' using Django 3.1.1. - -For more information on this file, see -https://docs.djangoproject.com/en/3.1/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.1/ref/settings/ -""" - -import json -import os -from pathlib import Path - -from django.core.exceptions import ImproperlyConfigured - -# prefix for urls in mails -URLPREFIX = 'http://localhost:8000' - -# mails in development go to stdout -EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' - -EMAIL_HOST = 'email.wikimedia.de' -EMAIL_PORT = '587' -EMAIL_USE_TLS = True -EMAIL_HOST_USER = '636ea784dd6ec43' -EMAIL_HOST_PASSWORD = 'wsgqp4ZaVRZZEpRJ' - - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - -# get secrets -with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file: - secrets = json.load(secrets_file) - -def get_secret(setting, secrets=secrets): - """Get secret setting or fail with ImproperlyConfigured""" - try: - return secrets[setting] - except KeyError: - raise ImproperlyConfigured("Set the {} setting".format(setting)) - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '*&7p9#_n$@^%0z49s+7jpy@+j1rw_hqh05knyd6y2*!0)r&b6h' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -STATIC_ROOT = BASE_DIR / 'staticfiles' - -ALLOWED_HOSTS = ['*'] - - -# Application definition - -INSTALLED_APPS = [ - 'input.apps.InputConfig', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'formtools', -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - '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 = 'foerderbarometer.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 = 'foerderbarometer.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/3.1/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': BASE_DIR / 'db.sqlite3', - 'PASSWORD': get_secret('DATABASE_PASSWORD') - } -} - - -# Password validation -# https://docs.djangoproject.com/en/3.1/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/3.1/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/3.1/howto/static-files/ - -STATIC_URL = '/static/' - -# needed since django 3.2 -DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' diff --git a/foerderbarometer/settings_mariadb_development.py b/foerderbarometer/settings_mariadb_development.py deleted file mode 100755 index 8f3c8b1..0000000 --- a/foerderbarometer/settings_mariadb_development.py +++ /dev/null @@ -1,175 +0,0 @@ -""" -Django settings for foerderbarometer project. - -Generated by 'django-admin startproject' using Django 3.1.1. - -For more information on this file, see -https://docs.djangoproject.com/en/3.1/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.1/ref/settings/ -""" - -import json -import os -from pathlib import Path - -from django.core.exceptions import ImproperlyConfigured - -# prefix for urls in mails -URLPREFIX = 'http://localhost:8000' - -# mails in development go to stdout -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - -# get secrets -with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file: - secrets = json.load(secrets_file) - -def get_secret(setting, secrets=secrets): - """Get secret setting or fail with ImproperlyConfigured""" - try: - return secrets[setting] - except KeyError: - raise ImproperlyConfigured("Set the {} setting".format(setting)) - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '*&7p9#_n$@^%0z49s+7jpy@+j1rw_hqh05knyd6y2*!0)r&b6h' - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -STATIC_ROOT = BASE_DIR / 'staticfiles' - -ALLOWED_HOSTS = ['*'] - - -# Application definition - -INSTALLED_APPS = [ - 'input.apps.InputConfig', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'formtools', -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - '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 = 'foerderbarometer.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 = 'foerderbarometer.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/3.1/ref/settings/#databases -# -# DATABASES = { -# 'default': { -# 'ENGINE': 'django.db.backends.sqlite3', -# 'NAME': BASE_DIR / 'db.sqlite3', -# 'PASSWORD': get_secret('DATABASE_PASSWORD') -# } -# } -# - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'fdb', - 'USER': 'fdb', - 'PASSWORD': get_secret('DATABASE_PASSWORD'), - 'HOST': 'localhost', # Or an IP Address that your database is hosted on - # 'PORT': '3306', - #optional: - 'OPTIONS': { - 'charset' : 'utf8', - 'use_unicode' : True, - 'init_command': 'SET ' - 'storage_engine=INNODB,' - 'character_set_connection=utf8,' - 'collation_connection=utf8_bin' - #'sql_mode=STRICT_TRANS_TABLES,' # see note below - #'SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', - }, - 'TEST_CHARSET': 'utf8', - 'TEST_COLLATION': 'utf8_general_ci', - } -} - -# Password validation -# https://docs.djangoproject.com/en/3.1/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/3.1/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/3.1/howto/static-files/ - -STATIC_URL = '/static/' - -# needed since django 3.2 -DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' diff --git a/foerderbarometer/settings_production.py b/foerderbarometer/settings_production.py deleted file mode 100755 index 7a77496..0000000 --- a/foerderbarometer/settings_production.py +++ /dev/null @@ -1,171 +0,0 @@ -""" -Django settings for foerderbarometer project. - -Generated by 'django-admin startproject' using Django 3.1.1. - -For more information on this file, see -https://docs.djangoproject.com/en/3.1/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.1/ref/settings/ -""" - -import json -import os -from pathlib import Path - -from django.core.exceptions import ImproperlyConfigured - -# mails in development go to stdout -EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' - -EMAIL_HOST = 'email.wikimedia.de' -EMAIL_PORT = '587' -EMAIL_USE_TLS = True -EMAIL_HOST_USER = '636ea784dd6ec43' -EMAIL_HOST_PASSWORD = 'wsgqp4ZaVRZZEpRJ' - -# prefix for urls in mails -URLPREFIX = 'http://foerderung.wikimedia.de' - - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - -# get secrets -with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file: - secrets = json.load(secrets_file) - -def get_secret(setting, secrets=secrets): - """Get secret setting or fail with ImproperlyConfigured""" - try: - return secrets[setting] - except KeyError: - raise ImproperlyConfigured("Set the {} setting".format(setting)) - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = get_secret('SECRET_KEY') - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False - -STATIC_ROOT = BASE_DIR / 'staticfiles' - -ALLOWED_HOSTS = ['*'] - - -# Application definition - -INSTALLED_APPS = [ - 'input.apps.InputConfig', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'formtools', -] - - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - '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 = 'foerderbarometer.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 = 'foerderbarometer.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/3.1/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'fdbdevel', - 'USER': 'fdbdevel', - 'PASSWORD': get_secret('DATABASE_PASSWORD'), - 'HOST': '10.0.6.7', # Or an IP Address that your database is hosted on - # 'PORT': '3306', - #optional: - 'OPTIONS': { - 'charset' : 'utf8', - 'use_unicode' : True, - 'init_command': 'SET ' - 'storage_engine=INNODB,' - 'character_set_connection=utf8,' - 'collation_connection=utf8_bin' - #'sql_mode=STRICT_TRANS_TABLES,' # see note below - #'SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', - }, - 'TEST_CHARSET': 'utf8', - 'TEST_COLLATION': 'utf8_general_ci', - } -} - -# Password validation -# https://docs.djangoproject.com/en/3.1/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/3.1/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/3.1/howto/static-files/ - -STATIC_URL = '/static/' diff --git a/input/asgi.py b/input/asgi.py deleted file mode 100644 index 2ff9254..0000000 --- a/input/asgi.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -ASGI config for oauth_demo project. - -It exposes the ASGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ -""" - -import os - -from django.core.asgi import get_asgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'oauth_demo.settings') - -application = get_asgi_application() diff --git a/input/forms.py b/input/forms.py index 1c787f6..eb2a50a 100755 --- a/input/forms.py +++ b/input/forms.py @@ -1,4 +1,4 @@ -from django.db import models +from django.conf import settings from django.forms import ModelForm, DateField, ChoiceField, RadioSelect, BooleanField from django.contrib.admin.widgets import AdminDateWidget from django.utils.html import format_html @@ -6,9 +6,6 @@ from django.utils.html import format_html from .models import Project, Volunteer, ConcreteVolunteer, Extern, ConcreteExtern, IFG, Library, TYPE_CHOICES,\ HonoraryCertificate, Travel, Email, Literature, List,\ BusinessCard -from .settings import DATAPROTECTION, FOERDERRICHTLINIEN, NUTZUNGSBEDINGUNGEN - -from . import settings @@ -39,7 +36,7 @@ class ExternForm(FdbForm): check = BooleanField(required=True, label=format_html("Ich stimme den Datenschutzbestimmungen und der
Richtlinie zur Förderung der Communitys zu", - DATAPROTECTION, FOERDERRICHTLINIEN)) + settings.DATAPROTECTION, settings.FOERDERRICHTLINIEN)) class Meta: model = ConcreteExtern @@ -116,7 +113,7 @@ class IFGForm(FdbForm): class CheckForm(FdbForm): - termstoaccept = NUTZUNGSBEDINGUNGEN + termstoaccept = settings.NUTZUNGSBEDINGUNGEN def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/input/management/commands/sendmails.py b/input/management/commands/sendmails.py index f22fa8f..dd8acdc 100755 --- a/input/management/commands/sendmails.py +++ b/input/management/commands/sendmails.py @@ -9,7 +9,6 @@ from django.conf import settings from input.models import Project, Library, HonoraryCertificate, Travel, Email,\ BusinessCard, List, IFG, Literature -from input.settings import IF_EMAIL, SURVEYPREFIX, SURVEY_EMAIL class Command(BaseCommand): ''' mails will be send here: @@ -34,14 +33,14 @@ class Command(BaseCommand): 'type': type, 'name': name, 'pid': pid, - 'SURVEYPREFIX': SURVEYPREFIX, } + 'SURVEY_PREFIX': settings.SURVEY_PREFIX, } txt_mail_template = get_template('input/survey_mail.txt') html_mail_template = get_template('input/survey_mail.html') try: - subject, from_email, to = 'Dein Feedback zur Förderung durch Wikimedia Deutschland', IF_EMAIL, email + subject, from_email, to = 'Dein Feedback zur Förderung durch Wikimedia Deutschland', settings.IF_EMAIL, email text_content = txt_mail_template.render(context) html_content = html_mail_template.render(context) - msg = EmailMultiAlternatives(subject, text_content, from_email, [to], bcc=[SURVEY_EMAIL]) + msg = EmailMultiAlternatives(subject, text_content, from_email, [to], bcc=[settings.SURVEY_EMAIL]) msg.attach_alternative(html_content, "text/html") msg.send() #print('survey mail would have been send') @@ -77,10 +76,10 @@ class Command(BaseCommand): for project in old: context = {'project': project} - context['URLPREFIX'] = settings.URLPREFIX - + context['URL_PREFIX'] = settings.EMAIL_URL_PREFIX + try: - subject, from_email, to = 'Projektende erreicht', IF_EMAIL, IF_EMAIL + subject, from_email, to = 'Projektende erreicht', settings.IF_EMAIL, settings.IF_EMAIL text_content = txt_mail_template.render(context) html_content = html_mail_template.render(context) msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) @@ -117,22 +116,22 @@ class Command(BaseCommand): txt_informMail_template = get_template('input/if_end_of_project_orginformed.txt') html_informMail_template = get_template('input/if_end_of_project_orginformed.html') # send the mail to project.email, which would be the mail of the volunteer filling out the form - + for project in approved_end: context = {'project': project} - context['URLPREFIX'] = settings.URLPREFIX - + context['URL_PREFIX'] = settings.EMAIL_URL_PREFIX + try: - subject, from_email, to = 'Projektende erreicht', IF_EMAIL, project.email + subject, from_email, to = 'Projektende erreicht', settings.IF_EMAIL, project.email text_content = txt_mail_template.render(context) html_content = html_mail_template.render(context) msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) msg.attach_alternative(html_content, "text/html") msg.send() #print('if and of project approved mail would have been sent') - - inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL + + inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', settings.IF_EMAIL, settings.IF_EMAIL inform_text_content = txt_informMail_template.render(context) inform_html_content = html_informMail_template.render(context) inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to]) @@ -178,9 +177,9 @@ class Command(BaseCommand): for project in approved_notHappened: context = {'project': project} - context['URLPREFIX'] = settings.URLPREFIX + context['URL_PREFIX'] = settings.EMAIL_URL_PREFIX try: - subject, from_email, to = 'Projektende erreicht', IF_EMAIL, project.email + subject, from_email, to = 'Projektende erreicht', settings.IF_EMAIL, project.email text_content = txt_mail_template.render(context) html_content = html_mail_template.render(context) msg = EmailMultiAlternatives(subject, text_content, from_email, [to]) @@ -194,8 +193,8 @@ class Command(BaseCommand): # IF_EMAIL, # [project.email], # fail_silently=False) - - inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', IF_EMAIL, IF_EMAIL + + inform_subject, inform_from_email, inform_to = 'Projektorganisator*in wurde informiert', settings.IF_EMAIL, settings.IF_EMAIL inform_text_content = txt_informMail_template.render(context) inform_html_content = html_informMail_template.render(context) inform_msg = EmailMultiAlternatives(inform_subject, inform_text_content, inform_from_email, [inform_to]) diff --git a/input/middleware/oauth.py b/input/middleware/oauth.py index 1e20cf9..a0499d4 100644 --- a/input/middleware/oauth.py +++ b/input/middleware/oauth.py @@ -1,11 +1,14 @@ from authlib.integrations.base_client import OAuthError from authlib.integrations.django_client import OAuth from authlib.oauth2.rfc6749 import OAuth2Token + from django.shortcuts import redirect from django.utils.deprecation import MiddlewareMixin -from foerderbarometer import settings -from input import views -from input import models +from django.conf import settings + +from input.models import Extern +from input.views import ExternView + class OAuthMiddleware(MiddlewareMixin): @@ -14,7 +17,7 @@ class OAuthMiddleware(MiddlewareMixin): self.oauth = OAuth() def process_request(self, request): - # added this if clause to get the landing page before oauth + # added this if-clause to get the landing page before oauth if request.path == '/': return self.get_response(request) if settings.OAUTH_URL_WHITELISTS is not None: @@ -37,12 +40,12 @@ class OAuthMiddleware(MiddlewareMixin): self.clear_session(request) request.session['token'] = sso_client.authorize_access_token(request) # print('blub', request.session['token']) - models.Extern.username = self.get_current_user(sso_client, request)['username'] + Extern.username = self.get_current_user(sso_client, request)['username'] if self.get_current_user(sso_client, request) is not None: redirect_uri = request.session.pop('redirect_uri', None) if redirect_uri is not None: return redirect(redirect_uri) - return redirect(views.ExternView) + return redirect(ExternView) if request.session.get('token', None) is not None: current_user = self.get_current_user(sso_client, request) diff --git a/input/models.py b/input/models.py index 90b7384..eeb335c 100755 --- a/input/models.py +++ b/input/models.py @@ -3,8 +3,6 @@ from datetime import date from django.db import models from django.utils.html import format_html -from .settings import ACCOUNTS - EMAIL_STATES = {'NONE': 'noch keine Mail versendet', 'INF': 'die Benachrichtigung zur Projektabschlussmail wurde versendet', diff --git a/input/settings.py b/input/settings.py deleted file mode 100755 index 5cca543..0000000 --- a/input/settings.py +++ /dev/null @@ -1,78 +0,0 @@ -# mail for IF-OTRS -IF_EMAIL = 'community@wikimedia.de' -#IF_EMAIL = 'test-luca-ext@wikimedia.de' -#SURVEY_EMAIL = 'christof.pins@wikimedia.de' -#SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' -SURVEY_EMAIL = 'sandro.halank@wikimedia.de' -# prefix for urls -SURVEYPREFIX = 'https://wikimedia.sslsurvey.de/Foerderbarometer/?' - -# some links -DATAPROTECTION = "https://www.wikimedia.de/datenschutz/#datenerfassung" -#FOERDERRICHTLINIEN = "https://de.wikipedia.org/wiki/Wikipedia:Wikimedia_Deutschland/F%C3%B6rderrichtlinien" -FOERDERRICHTLINIEN = "https://de.wikipedia.org/wiki/Wikipedia:Wikimedia_Deutschland/Richtlinie_zur_Förderung_der_Communitys" - -NUTZUNGSBEDINGUNGEN = 'static/input/nutzungsbedingungen.html' -NUTZUNGSBEDINGUNGEN_EMAIL_SERVICE = 'static/input/nutzungsbedingungen-mail.pdf' -NUTZUNGSBEDINGUNGEN_MAILINGLISTEN = 'static/input/nutzungsbedingungen-mailinglisten.pdf' -NUTZUNGSBEDINGUNGEN_LITERATURSTIPENDIUM = 'static/input/nutzungsbedingungen-literaturstipendium.pdf' -NUTZUNGSBEDINGUNGEN_OTRS = 'static/input/2025_Nutzungsvereinbarung_OTRS.docx.pdf' -NUTZUNGSBEDINGUNGEN_VISITENKARTEN = 'static/input/nutzungsbedingungen-visitenkarten.pdf' - -LANGUAGE_CODE = 'de' -TIME_ZONE = 'UTC' -USE_I18N = True -USE_L10N = True -USE_TZ = True - - -ACCOUNTS ={ # "21103": '21103 Willkommen', - "DEF": 'DEFAULT VALUE, you hould not see this!', - "21111": '21111 Förderung (reaktiv)', - "21112": '21112 WikiCon', -# "21113": '21113 Wikimania/Unterstützung Ehrenamtliche', - "21115": '21115 Lokale Räume, Berlin', - "21116": '21116 Lokale Räume, Hamburg', - "21117": '21117 Lokale Räume, Hannover', - "21118": '21118 Lokale Räume, Köln', - "21119": '21119 Lokale Räume, München', - "21120": '21120 Lokale Räume, Fürth', - "21125": '21125 Lokale Räume, allgemein', - "21130": '21130 GLAM-Förderung', - "21131": '21131 Initiative Förderung', -# "21134": '21134 Größe', -# "21137": '21137 Beitragen', -# "21138": '21138 Vermittlung', - "21140": '21140 Wikipedia-Kampagne', - "21141": '21141 Wikipedia-Onboarding', - "21150": '21150 Fürsorge und Online-Kommunikationskultur',} - - - -# teken from working oauth prototype as additional settings - -WSGI_APPLICATION = 'oauth_demo.wsgi.application' - -# OAuth Settings -OAUTH_URL_WHITELISTS = [] - -OAUTH_CLIENT_NAME = '' - - - -OAUTH_CLIENT = { - 'client_id': '', - 'client_secret': '', - 'access_token_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/access_token', - 'authorize_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/authorize', - 'api_base_url': 'https://meta.wikimedia.org/w/rest.php/oauth2/resource', - 'redirect_uri': 'http://localhost:8000/oauth/callback', - 'client_kwargs': { - 'scope': 'basic', - 'token_placement': 'header' - }, - 'userinfo_endpoint': 'resource/profile', -} - -OAUTH_COOKIE_SESSION_ID = 'sso_session_id' - diff --git a/input/settings.py.old b/input/settings.py.old deleted file mode 100755 index 3b43e9a..0000000 --- a/input/settings.py.old +++ /dev/null @@ -1,41 +0,0 @@ -# mail for IF-OTRS -IF_EMAIL = 'community@wikimedia.de' -#IF_EMAIL = 'test-luca-ext@wikimedia.de' -#SURVEY_EMAIL = 'christof.pins@wikimedia.de' -#SURVEY_EMAIL = 'luca.wulf@cannabinieri.de' -SURVEY_EMAIL = 'sandro.halank@wikimedia.de' -# prefix for urls -SURVEYPREFIX = 'https://wikimedia.sslsurvey.de/Foerderbarometer/?' - -# some links -DATAPROTECTION = "https://www.wikimedia.de/datenschutz/#datenerfassung" -FOERDERRICHTLINIEN = "https://de.wikipedia.org/wiki/Wikipedia:Wikimedia_Deutschland/F%C3%B6rderrichtlinien" -NUTZUNGSBEDINGUNGEN = 'static/input/nutzungsbedingungen.html' - -LANGUAGE_CODE = 'de' -TIME_ZONE = 'UTC' -USE_I18N = True -USE_L10N = True -USE_TZ = True - - -ACCOUNTS ={ # "21103": '21103 Willkommen', - "DEF": 'DEFAULT VALUE, you hould not see this!', - "21111": '21111 Förderung (reaktiv)', - "21112": '21112 WikiCon', -# "21113": '21113 Wikimania/Unterstützung Ehrenamtliche', - "21115": '21115 Lokale Räume, Berlin', - "21116": '21116 Lokale Räume, Hamburg', - "21117": '21117 Lokale Räume, Hannover', - "21118": '21118 Lokale Räume, Köln', - "21119": '21119 Lokale Räume, München', - "21120": '21120 Lokale Räume, Fürth', - "21125": '21125 Lokale Räume, allgemein', - "21130": '21130 GLAM-Förderung', - "21131": '21131 Initiative Förderung', -# "21134": '21134 Größe', -# "21137": '21137 Beitragen', -# "21138": '21138 Vermittlung', - "21140": '21140 Wikipedia-Kampagne', - "21141": '21141 Wikipedia-Onboarding', - "21150": '21150 Fürsorge und Online-Kommunikationskultur',} diff --git a/input/templates/input/if_end_of_project.html b/input/templates/input/if_end_of_project.html index e52b86c..94a7f1f 100755 --- a/input/templates/input/if_end_of_project.html +++ b/input/templates/input/if_end_of_project.html @@ -8,7 +8,7 @@ Ende erreicht.

Hier könnt ihr es in der Datenbank editieren:

-{{URLPREFIX}}/admin/input/project/{{project.pk}}/change +{{URL_PREFIX}}/admin/input/project/{{project.pk}}/change

mit freundlichen Grüßen, Eure Lieblingsdatenbank diff --git a/input/templates/input/if_end_of_project.txt b/input/templates/input/if_end_of_project.txt index 90934aa..fa92e3a 100755 --- a/input/templates/input/if_end_of_project.txt +++ b/input/templates/input/if_end_of_project.txt @@ -5,6 +5,6 @@ Ende erreicht. Hier könnt ihr es in der Datenbank editieren: -{{URLPREFIX}}/admin/input/project/{{project.pk}}/change +{{URL_PREFIX}}/admin/input/project/{{project.pk}}/change mit freundlichen Grüßen, Eure Lieblingsdatenbank diff --git a/input/templates/input/if_end_of_project_orginformed.html b/input/templates/input/if_end_of_project_orginformed.html index 83ad2d3..7f461a9 100755 --- a/input/templates/input/if_end_of_project_orginformed.html +++ b/input/templates/input/if_end_of_project_orginformed.html @@ -8,7 +8,7 @@ Ende erreicht.

Hier könnt ihr es in der Datenbank editieren:

-{{URLPREFIX}}/admin/input/project/{{project.pk}}/change +{{URL_PREFIX}}/admin/input/project/{{project.pk}}/change

Projektorganisator*in wurde über den Projektabschluss informiert. diff --git a/input/templates/input/if_end_of_project_orginformed.txt b/input/templates/input/if_end_of_project_orginformed.txt index 05b12a3..388c471 100755 --- a/input/templates/input/if_end_of_project_orginformed.txt +++ b/input/templates/input/if_end_of_project_orginformed.txt @@ -5,7 +5,7 @@ Ende erreicht. Hier könnt ihr es in der Datenbank editieren: -{{URLPREFIX}}/admin/input/project/{{project.pk}}/change +{{URL_PREFIX}}/admin/input/project/{{project.pk}}/change Projektorganisator*in wurde über den Projektabschluss informiert. diff --git a/input/templates/input/if_mail.html b/input/templates/input/if_mail.html index efd2941..6e76f50 100755 --- a/input/templates/input/if_mail.html +++ b/input/templates/input/if_mail.html @@ -28,29 +28,29 @@ Sendungsadrese: {{data.send_to}}
{% endif %} Zum Eintrag in der Förderdatenbank: {% if data.choice == 'BIB' %} -{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{{data.url_prefix}}/admin/input/library/{{data.pk}}/change {% elif data.choice == 'ELIT'%} -{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{{data.url_prefix}}/admin/input/library/{{data.pk}}/change {% elif data.choice == 'LIT'%} -{{data.urlprefix}}/admin/input/literature/{{data.pk}}/change +{{data.url_prefix}}/admin/input/literature/{{data.pk}}/change {% elif data.choice == 'MAIL'%} -{{data.urlprefix}}/admin/input/email/{{data.pk}}/change +{{data.url_prefix}}/admin/input/email/{{data.pk}}/change {% elif data.choice == 'IFG'%} -{{data.urlprefix}}/admin/input/ifg/{{data.pk}}/change +{{data.url_prefix}}/admin/input/ifg/{{data.pk}}/change {% elif data.choice == 'LIST'%} -{{data.urlprefix}}/admin/input/list/{{data.pk}}/change +{{data.url_prefix}}/admin/input/list/{{data.pk}}/change {% elif data.choice == 'TRAV'%} -{{data.urlprefix}}/admin/input/travel/{{data.pk}}/change +{{data.url_prefix}}/admin/input/travel/{{data.pk}}/change {% elif data.choice == 'SOFT'%} -{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{{data.url_prefix}}/admin/input/library/{{data.pk}}/change {% elif data.choice == 'VIS'%} -{{data.urlprefix}}/admin/input/businesscard/{{data.pk}}/change +{{data.url_prefix}}/admin/input/businesscard/{{data.pk}}/change {% endif %}

-Zum Genehmigen hier klicken: {{data.urlprefix}}{% url 'authorize' data.choice data.pk %} +Zum Genehmigen hier klicken: {{data.url_prefix}}{% url 'authorize' data.choice data.pk %}

-Zu Ablehnen hier klicken: {{data.urlprefix}}{% url 'deny' data.choice data.pk %} +Zu Ablehnen hier klicken: {{data.url_prefix}}{% url 'deny' data.choice data.pk %}

Stets zu Diensten, Deine Förderdatenbank diff --git a/input/templates/input/if_mail.txt b/input/templates/input/if_mail.txt index 4cb0375..afee396 100755 --- a/input/templates/input/if_mail.txt +++ b/input/templates/input/if_mail.txt @@ -23,30 +23,30 @@ Persönliche Daten: {{data.data}} Variante: {{data.variant}} Sendungsadrese: {{data.send_to}} {% endif %} -Zum Eintrag in der Förderdatenbank: +Zum Eintrag in der Förderdatenbank: {% if data.choice == 'BIB' %} -{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{{data.url_prefix}}/admin/input/library/{{data.pk}}/change {% elif data.choice == 'ELIT'%} -{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{{data.url_prefix}}/admin/input/library/{{data.pk}}/change {% elif data.choice == 'LIT'%} -{{data.urlprefix}}/admin/input/literature/{{data.pk}}/change +{{data.url_prefix}}/admin/input/literature/{{data.pk}}/change {% elif data.choice == 'MAIL'%} -{{data.urlprefix}}/admin/input/email/{{data.pk}}/change +{{data.url_prefix}}/admin/input/email/{{data.pk}}/change {% elif data.choice == 'IFG'%} -{{data.urlprefix}}/admin/input/ifg/{{data.pk}}/change +{{data.url_prefix}}/admin/input/ifg/{{data.pk}}/change {% elif data.choice == 'LIST'%} -{{data.urlprefix}}/admin/input/list/{{data.pk}}/change +{{data.url_prefix}}/admin/input/list/{{data.pk}}/change {% elif data.choice == 'TRAV'%} -{{data.urlprefix}}/admin/input/travel/{{data.pk}}/change +{{data.url_prefix}}/admin/input/travel/{{data.pk}}/change {% elif data.choice == 'SOFT'%} -{{data.urlprefix}}/admin/input/library/{{data.pk}}/change +{{data.url_prefix}}/admin/input/library/{{data.pk}}/change {% elif data.choice == 'VIS'%} -{{data.urlprefix}}/admin/input/businesscard/{{data.pk}}/change +{{data.url_prefix}}/admin/input/businesscard/{{data.pk}}/change {% endif %} -Zum Genehmigen hier klicken: {{data.urlprefix}}{% url 'authorize' data.choice data.pk %} +Zum Genehmigen hier klicken: {{data.url_prefix}}{% url 'authorize' data.choice data.pk %} -Zu Ablehnen hier klicken: {{data.urlprefix}}{% url 'deny' data.choice data.pk %} +Zu Ablehnen hier klicken: {{data.url_prefix}}{% url 'deny' data.choice data.pk %} Stets zu Diensten, Deine Förderdatenbank diff --git a/input/templates/input/survey_mail.html b/input/templates/input/survey_mail.html index bc381ae..14ae686 100755 --- a/input/templates/input/survey_mail.html +++ b/input/templates/input/survey_mail.html @@ -34,7 +34,7 @@ Förderprogramme im Sinne der Communitys weiter zu verbessern. Wir freuen uns, wenn du dir kurz die Zeit dafür nehmen würdest. Die Umfrage mit weiteren Informationen findest du unter dem folgenden Link:
-{{SURVEYPREFIX}}{% if type == 'PRO' %}O{% else %}I{% endif %}=1&{{pid}}=1

+{{SURVEY_PREFIX}}{% if type == 'PRO' %}O{% else %}I{% endif %}=1&{{pid}}=1

Da dies eine automatisch erzeugte Nachricht ist, wende dich bei Rückfragen zur Umfrage bitte an community@wikimedia.de diff --git a/input/templates/input/survey_mail.txt b/input/templates/input/survey_mail.txt index 9dbaded..8d22a86 100755 --- a/input/templates/input/survey_mail.txt +++ b/input/templates/input/survey_mail.txt @@ -32,6 +32,6 @@ Förderprogramme im Sinne der Communitys weiter zu verbessern. Wir freuen uns, wenn du dir kurz die Zeit dafür nehmen würdest. Die Umfrage mit weiteren Informationen findest du unter dem folgenden Link: -{{SURVEYPREFIX}}{% if type == 'PRO' %}O{% else %}I{% endif %}=1&{{pid}}=1 +{{SURVEY_PREFIX}}{% if type == 'PRO' %}O{% else %}I{% endif %}=1&{{pid}}=1 Da dies eine automatisch erzeugte Nachricht ist, wende dich bei Rückfragen zur Umfrage bitte an community@wikimedia.de diff --git a/input/utils/confirmation.py b/input/utils/confirmation.py new file mode 100644 index 0000000..002dcc7 --- /dev/null +++ b/input/utils/confirmation.py @@ -0,0 +1,54 @@ +YES_NO = { + 'y': True, + 'Y': True, + 'yes': True, + 'YES': True, + 'n': False, + 'N': False, + 'no': False, + 'NO': False, +} + +ZERO_ONE = { + 1: True, + '1': True, + 0: False, + '0': False, +} + +TRUE_FALSE = { + True: True, + 'TRUE': True, + 'True': True, + 'true': True, + 't': True, + False: False, + 'FALSE': False, + 'False': False, + 'false': False, + 'f': False, + None: False, +} + +ON_OFF = { + 'on': True, + 'ON': True, + 'off': False, + 'OFF': False, +} + +TRUTHY = { + **YES_NO, + **ZERO_ONE, + **TRUE_FALSE, + **ON_OFF, +} + + +def ask(question, default=False, truthy=None): + response = input(question).strip() + + return (truthy or YES_NO).get(response, default) + + +confirm = ask diff --git a/input/utils/settings.py b/input/utils/settings.py new file mode 100644 index 0000000..cc6598f --- /dev/null +++ b/input/utils/settings.py @@ -0,0 +1,42 @@ +import os + +from .confirmation import TRUTHY + + +def env(key, default=None, parser=None): + value = os.environ.get(key) + + if value is None: + return default + + if parser is None: + if default is None: + return value + else: + parser = type(default) + + if parser is bool: + return truthy(value, default) + + return parser(value) + + +def truthy(value, default=False): + return TRUTHY.get(value, default) + + +def password_validators(*validators): + return list(_parse_password_validators(validators)) + + +def _parse_password_validators(validators): + for validator in validators: + if isinstance(validator, (tuple, list)): + validator, options = validator + else: + validator, options = validator, {} + + if '.' not in validator: + validator = 'django.contrib.auth.password_validation.%s' % validator + + yield dict(NAME=validator, OPTIONS=options) diff --git a/input/views.py b/input/views.py index 60fd831..e3933c8 100755 --- a/input/views.py +++ b/input/views.py @@ -9,6 +9,7 @@ from django.core.mail import send_mail, BadHeaderError, EmailMultiAlternatives from django.conf import settings from django.template.loader import get_template from django.template import Context +from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from django.utils.html import format_html @@ -18,7 +19,6 @@ from .forms import ProjectForm, ExternForm, LibraryForm, IFGForm, LiteratureForm HonoraryCertificateForm, InternForm, TravelForm, EmailForm,\ ListForm, BusinessCardForm, INTERN_CHOICES from .models import Project, TYPE_CHOICES, Library, Literature, Travel, IFG, BusinessCard, Email, List -from .settings import IF_EMAIL def auth_deny(choice,pk,auth): if choice in ('BIB', 'ELIT', 'SOFT'): @@ -244,7 +244,7 @@ class ExternView(CookieWizardView): # add some data to context for mail templates data['pk'] = modell.pk - data['urlprefix'] = settings.URLPREFIX + data['url_prefix'] = settings.EMAIL_URL_PREFIX data['grant'] = ('LIT', 'SOFT', 'ELIT', 'BIB', 'IFG') data['DOMAIN'] = ('MAIL', 'LIST') data['typestring'] = TYPE_CHOICES[data['choice']] @@ -257,7 +257,7 @@ class ExternView(CookieWizardView): txt_mail_template1 = get_template('input/ifg_volunteer_mail.txt') html_mail_template1 = get_template('input/ifg_volunteer_mail.html') - subject1, from_email1, to1 = 'Formular ausgefüllt', IF_EMAIL, data['email'] + subject1, from_email1, to1 = 'Formular ausgefüllt', settings.IF_EMAIL, data['email'] text_content1 = txt_mail_template1.render(context) html_content1 = html_mail_template1.render(context) msg1 = EmailMultiAlternatives(subject1, text_content1, from_email1, [to1]) @@ -275,7 +275,7 @@ class ExternView(CookieWizardView): txt_mail_template = get_template('input/if_mail.txt') html_mail_template = get_template('input/if_mail.html') - subject, from_email, to = 'Formular ausgefüllt', IF_EMAIL, IF_EMAIL + subject, from_email, to = 'Formular ausgefüllt', settings.IF_EMAIL, settings.IF_EMAIL text_content = txt_mail_template.render(context) html_content = html_mail_template.render(context) msg2 = EmailMultiAlternatives(subject, text_content, from_email, [to]) diff --git a/requirements.txt b/requirements.txt index a1371f1..5140d37 100755 --- a/requirements.txt +++ b/requirements.txt @@ -11,6 +11,7 @@ gunicorn==20.0.4 idna==3.4 mysqlclient==2.1.1 pycparser==2.21 +python-dotenv==1.1.1 pytz==2023.3.post1 requests==2.31.0 six==1.16.0