Merge branch 'Kerl/test_user_creation'
This commit is contained in:
commit
1ffbac92cb
16 changed files with 464 additions and 195 deletions
25
README.md
25
README.md
|
@ -0,0 +1,25 @@
|
||||||
|
# Gestion Événementiel
|
||||||
|
|
||||||
|
## Vagrant
|
||||||
|
|
||||||
|
### Production-like environment
|
||||||
|
|
||||||
|
Our Vagrant setup provides two ways of running GestionEvenementiel:
|
||||||
|
|
||||||
|
1. You can run the usual development server with:
|
||||||
|
|
||||||
|
python manage.py runserver 0.0.0.0:8000
|
||||||
|
|
||||||
|
Please note that we specify the interface `0.0.0.0` to make the server
|
||||||
|
reachable outside the VM at address `localhost:8000`
|
||||||
|
|
||||||
|
2. A second instance, more similar to the production environment, runs with
|
||||||
|
Daphne and nginx in the VM. It runs permanently by default but is not
|
||||||
|
reloaded when you update the code. To restart this server, type:
|
||||||
|
|
||||||
|
python manage.py collectstatic --noinput
|
||||||
|
sudo systemctl restart daphne.service worker.service
|
||||||
|
|
||||||
|
To query this instance from the host, you have to use the address
|
||||||
|
`localhost:8080`. It is a good practice to ensure that this instance works
|
||||||
|
before submitting a merge request (although it might break sometimes).
|
2
Vagrantfile
vendored
2
Vagrantfile
vendored
|
@ -10,7 +10,7 @@ Vagrant.configure(2) do |config|
|
||||||
# For a complete reference, please see the online documentation at
|
# For a complete reference, please see the online documentation at
|
||||||
# https://docs.vagrantup.com.
|
# https://docs.vagrantup.com.
|
||||||
|
|
||||||
config.vm.box = "ubuntu/trusty64"
|
config.vm.box = "debian/contrib-jessie64"
|
||||||
|
|
||||||
# On associe le port 80 dans la machine virtuelle avec le port 8080 de notre
|
# On associe le port 80 dans la machine virtuelle avec le port 8080 de notre
|
||||||
# ordinateur, et le port 8000 avec le port 8000.
|
# ordinateur, et le port 8000 avec le port 8000.
|
||||||
|
|
7
evenementiel/asgi.py
Normal file
7
evenementiel/asgi.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import os
|
||||||
|
from channels.asgi import get_channel_layer
|
||||||
|
|
||||||
|
if "DJANGO_SETTINGS_MODULE" not in os.environ:
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "evenementiel.settings")
|
||||||
|
|
||||||
|
channel_layer = get_channel_layer()
|
2
evenementiel/routing.py
Normal file
2
evenementiel/routing.py
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# Nothing yet
|
||||||
|
channel_routing = []
|
1
evenementiel/settings/.gitignore
vendored
Normal file
1
evenementiel/settings/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
secret.py
|
146
evenementiel/settings/common.py
Normal file
146
evenementiel/settings/common.py
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Django common settings for GestionÉvénementiel
|
||||||
|
|
||||||
|
Everything which is supposed to be identical between the production server and
|
||||||
|
the local development server should be here.
|
||||||
|
|
||||||
|
We also load the secrets in this file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from . import secret
|
||||||
|
|
||||||
|
|
||||||
|
def import_secret(name):
|
||||||
|
"""
|
||||||
|
Shorthand for importing a value from the secret module and raising an
|
||||||
|
informative exception if a secret is missing.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return getattr(secret, name)
|
||||||
|
except AttributeError:
|
||||||
|
raise RuntimeError("Secret missing: {}".format(name))
|
||||||
|
|
||||||
|
|
||||||
|
SECRET_KEY = import_secret("SECRET_KEY")
|
||||||
|
ADMINS = import_secret("ADMINS")
|
||||||
|
|
||||||
|
DBNAME = import_secret("DBNAME")
|
||||||
|
DBUSER = import_secret("DBUSER")
|
||||||
|
DBPASSWD = import_secret("DBPASSWD")
|
||||||
|
|
||||||
|
REDIS_PASSWD = import_secret("REDIS_PASSWD")
|
||||||
|
REDIS_DB = import_secret("REDIS_DB")
|
||||||
|
REDIS_HOST = import_secret("REDIS_HOST")
|
||||||
|
REDIS_PORT = import_secret("REDIS_PORT")
|
||||||
|
|
||||||
|
CREATE_USER_KEY = import_secret("CREATE_USER_KEY")
|
||||||
|
|
||||||
|
|
||||||
|
BASE_DIR = os.path.dirname(
|
||||||
|
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'equipment.apps.EquipmentConfig',
|
||||||
|
'event.apps.EventConfig',
|
||||||
|
'users.apps.UsersConfig',
|
||||||
|
'shared.apps.SharedConfig',
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
'channels',
|
||||||
|
'bootstrapform',
|
||||||
|
'widget_tweaks',
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE_CLASSES = [
|
||||||
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'evenementiel.urls'
|
||||||
|
|
||||||
|
STATIC_URL = "/static/"
|
||||||
|
MEDIA_URL = "/media/"
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL = 'shared:home'
|
||||||
|
LOGOUT_REDIRECT_URL = 'shared:home'
|
||||||
|
|
||||||
|
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',
|
||||||
|
'shared.shared.context_processor',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
|
'NAME': DBNAME,
|
||||||
|
'USER': DBUSER,
|
||||||
|
'PASSWORD': DBPASSWD,
|
||||||
|
'PORT': 5432,
|
||||||
|
'HOST': 'localhost',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHANNEL_LAYERS = {
|
||||||
|
"default": {
|
||||||
|
"BACKEND": "asgi_redis.RedisChannelLayer",
|
||||||
|
"CONFIG": {
|
||||||
|
"hosts": [(
|
||||||
|
"redis://:{passwd}@{host}:{port}/{db}"
|
||||||
|
.format(passwd=REDIS_PASSWD, host=REDIS_HOST,
|
||||||
|
port=REDIS_PORT, db=REDIS_DB)
|
||||||
|
)],
|
||||||
|
},
|
||||||
|
"ROUTING": "evenementiel.routing.channel_routing",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Password validation
|
||||||
|
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{'NAME': 'django.contrib.auth.password_validation'
|
||||||
|
'.UserAttributeSimilarityValidator'},
|
||||||
|
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'},
|
||||||
|
{'NAME': 'django.contrib.auth.password_validation'
|
||||||
|
'.CommonPasswordValidator'},
|
||||||
|
{'NAME': 'django.contrib.auth.password_validation'
|
||||||
|
'.NumericPasswordValidator'},
|
||||||
|
]
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_L10N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
44
evenementiel/settings/dev.py
Normal file
44
evenementiel/settings/dev.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
"""
|
||||||
|
Django development settings for GestionÉvénementiel
|
||||||
|
The settings that are not listed here are imported from .common
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .common import * # NOQA
|
||||||
|
|
||||||
|
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||||
|
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
# Add some debugging tools
|
||||||
|
INSTALLED_APPS += ["debug_toolbar", "debug_panel"] # NOQA
|
||||||
|
MIDDLEWARE_CLASSES = (
|
||||||
|
["debug_panel.middleware.DebugPanelMiddleware"]
|
||||||
|
+ MIDDLEWARE_CLASSES # NOQA
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Nginx static/media config
|
||||||
|
# ---
|
||||||
|
|
||||||
|
STATIC_ROOT = "/srv/GE/static/"
|
||||||
|
MEDIA_ROOT = "/srv/GE/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.
|
||||||
|
"""
|
||||||
|
return DEBUG # True
|
||||||
|
|
||||||
|
DEBUG_TOOLBAR_CONFIG = {
|
||||||
|
'SHOW_TOOLBAR_CALLBACK': show_toolbar,
|
||||||
|
}
|
16
evenementiel/settings/secret_example.py
Normal file
16
evenementiel/settings/secret_example.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
SECRET_KEY = 'dummy_key3i%5cp4)f+ww4-28_w+ly3q9=6imw2ciu&_(5_4ah'
|
||||||
|
ADMINS = None
|
||||||
|
|
||||||
|
# Postgres
|
||||||
|
DBNAME = "{{DBNAME}}"
|
||||||
|
DBUSER = "{{DBUSER}}"
|
||||||
|
DBPASSWD = "{{DBPASSWD}}"
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
REDIS_PASSWD = "{{REDIS_PASSWD}}"
|
||||||
|
REDIS_PORT = 6379
|
||||||
|
REDIS_DB = 0
|
||||||
|
REDIS_HOST = "127.0.0.1"
|
||||||
|
|
||||||
|
# An other secret key used for user creation
|
||||||
|
CREATE_USER_KEY = "lolilol"
|
|
@ -1,162 +0,0 @@
|
||||||
"""
|
|
||||||
Django settings for evenementiel project.
|
|
||||||
|
|
||||||
Generated by 'django-admin startproject' using Django 1.9.9.
|
|
||||||
|
|
||||||
For more information on this file, see
|
|
||||||
https://docs.djangoproject.com/en/1.9/topics/settings/
|
|
||||||
|
|
||||||
For the full list of settings and their values, see
|
|
||||||
https://docs.djangoproject.com/en/1.9/ref/settings/
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
from django.core.urlresolvers import reverse_lazy
|
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
|
|
||||||
|
|
||||||
# Quick-start development settings - unsuitable for production
|
|
||||||
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
|
|
||||||
|
|
||||||
# SECURITY WARNING: keep the secret key used in production secret!
|
|
||||||
SECRET_KEY = '0@=@$0*2x)x=$6qzf*1a(07she(33zr9vi0+=(yd%3i=i9gp+_'
|
|
||||||
CREATE_USER_KEY = 'lolilol' # Do not use this one on prod !!
|
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
|
||||||
DEBUG = True
|
|
||||||
|
|
||||||
ALLOWED_HOSTS = []
|
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
|
||||||
'equipment.apps.EquipmentConfig',
|
|
||||||
'event.apps.EventConfig',
|
|
||||||
'users.apps.UsersConfig',
|
|
||||||
'shared.apps.SharedConfig',
|
|
||||||
'django.contrib.admin',
|
|
||||||
'django.contrib.auth',
|
|
||||||
'django.contrib.contenttypes',
|
|
||||||
'django.contrib.sessions',
|
|
||||||
'django.contrib.messages',
|
|
||||||
'django.contrib.staticfiles',
|
|
||||||
'bootstrapform',
|
|
||||||
'debug_toolbar',
|
|
||||||
'widget_tweaks',
|
|
||||||
]
|
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = [
|
|
||||||
'debug_toolbar.middleware.DebugToolbarMiddleware',
|
|
||||||
'django.middleware.security.SecurityMiddleware',
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
||||||
'django.middleware.common.CommonMiddleware',
|
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
||||||
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
|
||||||
]
|
|
||||||
|
|
||||||
ROOT_URLCONF = 'evenementiel.urls'
|
|
||||||
|
|
||||||
LOGIN_REDIRECT_URL = reverse_lazy('shared:home')
|
|
||||||
LOGOUT_REDIRECT_URL = reverse_lazy('shared:home')
|
|
||||||
|
|
||||||
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',
|
|
||||||
'shared.shared.context_processor',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
WSGI_APPLICATION = 'evenementiel.wsgi.application'
|
|
||||||
|
|
||||||
|
|
||||||
# Database
|
|
||||||
# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
|
|
||||||
|
|
||||||
# # MySQL
|
|
||||||
# DATABASES = {
|
|
||||||
# 'default': {
|
|
||||||
# 'ENGINE': 'django.db.backends.sqlite3',
|
|
||||||
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# PostGreSQL
|
|
||||||
DATABASES = {
|
|
||||||
'default': {
|
|
||||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
|
||||||
'NAME': os.environ['DBNAME'],
|
|
||||||
'USER': os.environ['DBUSER'],
|
|
||||||
'PASSWORD': os.environ['DBPASSWD'],
|
|
||||||
'PORT': 5432,
|
|
||||||
'HOST': 'localhost',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Password validation
|
|
||||||
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
|
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
|
||||||
{'NAME': 'django.contrib.auth.password_validation'
|
|
||||||
'.UserAttributeSimilarityValidator'},
|
|
||||||
{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'},
|
|
||||||
{'NAME': 'django.contrib.auth.password_validation'
|
|
||||||
'.CommonPasswordValidator'},
|
|
||||||
{'NAME': 'django.contrib.auth.password_validation'
|
|
||||||
'.NumericPasswordValidator'},
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
|
||||||
# https://docs.djangoproject.com/en/1.9/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/1.9/howto/static-files/
|
|
||||||
|
|
||||||
STATIC_URL = '/static/'
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
|
||||||
"""
|
|
||||||
if not DEBUG:
|
|
||||||
return False
|
|
||||||
if request.is_ajax():
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
DEBUG_TOOLBAR_CONFIG = {
|
|
||||||
'SHOW_TOOLBAR_CALLBACK': show_toolbar,
|
|
||||||
}
|
|
|
@ -1,45 +1,125 @@
|
||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
|
|
||||||
# Configuration de la base de données. Le mot de passe est constant car c'est
|
# The credentials of the database. Can be public since they will only be used in
|
||||||
# pour une installation de dév locale qui ne sera accessible que depuis la
|
# the local development environment
|
||||||
# machine virtuelle.
|
|
||||||
DBUSER="event_gestion"
|
DBUSER="event_gestion"
|
||||||
DBNAME="event_gestion"
|
DBNAME="event_gestion"
|
||||||
DBPASSWD="4KZt3nGPLVeWSvtBZPsd9jdssdJMds78"
|
DBPASSWD="4KZt3nGPLVeWSvtBZPsd9jdssdJMds78"
|
||||||
|
|
||||||
# Installation de paquets utiles
|
# Not critical either
|
||||||
apt-get update && apt-get install -y python3-pip python3-dev \
|
REDIS_PASSWD="dummy"
|
||||||
libpq-dev postgresql postgresql-contrib libjpeg-dev
|
|
||||||
|
|
||||||
# Setup Database and User
|
# It is used in quite a few places
|
||||||
|
SETTINGS="evenementiel.settings.dev"
|
||||||
|
|
||||||
|
# Fills a "templated file" with the information specified in the variables above
|
||||||
|
# e.g. every occurrence of {{DBUSER}} in the file will be replaced by the value
|
||||||
|
# of the variable $DBUSER
|
||||||
|
function fill_template {
|
||||||
|
sed "s/{{DBUSER}}/$DBUSER/" -i $1
|
||||||
|
sed "s/{{DBNAME}}/$DBNAME/" -i $1
|
||||||
|
sed "s/{{DBPASSWD}}/$DBPASSWD/" -i $1
|
||||||
|
sed "s/{{REDIS_PASSWD}}/$REDIS_PASSWD/" -i $1
|
||||||
|
sed "s/{{SETTINGS}}/$SETTINGS/" -i $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Installs the dependencies
|
||||||
|
# ---
|
||||||
|
|
||||||
|
# System packages
|
||||||
|
apt-get update && apt-get upgrade -y
|
||||||
|
apt-get install -y python3-pip python3-dev python3-venv libpq-dev postgresql \
|
||||||
|
postgresql-contrib libjpeg-dev nginx redis-server
|
||||||
|
|
||||||
|
# Python packages, in a virtual environment
|
||||||
|
sudo -H -u vagrant python3 -m venv ~vagrant/venv
|
||||||
|
sudo -H -u vagrant ~vagrant/venv/bin/pip install -U pip wheel
|
||||||
|
sudo -H -u vagrant ~vagrant/venv/bin/pip install -U -r /vagrant/requirements-devel.txt
|
||||||
|
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Setup the production-like environment
|
||||||
|
# ---
|
||||||
|
|
||||||
|
# Database and User
|
||||||
sudo -u postgres createdb $DBNAME
|
sudo -u postgres createdb $DBNAME
|
||||||
sudo -u postgres createuser -SDR $DBUSER
|
sudo -u postgres createuser -SDR $DBUSER
|
||||||
sudo -u postgres psql -c "ALTER USER $DBUSER WITH PASSWORD '$DBPASSWD';"
|
sudo -u postgres psql -c "ALTER USER $DBUSER WITH PASSWORD '$DBPASSWD';"
|
||||||
sudo -u postgres psql -c "ALTER USER $DBUSER CREATEDB;"
|
sudo -u postgres psql -c "ALTER USER $DBUSER CREATEDB;"
|
||||||
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DBNAME TO $DBUSER;"
|
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DBNAME TO $DBUSER;"
|
||||||
|
|
||||||
# Mise en place du .bash_profile pour tout configurer lors du `vagrant ssh`
|
# The working directory for Daphne and cie
|
||||||
|
mkdir -p /srv/GE/{media,static}
|
||||||
|
chown -R vagrant:vagrant /srv/GE
|
||||||
|
|
||||||
|
# Nginx
|
||||||
|
cp /vagrant/provisioning/nginx.conf /etc/nginx/sites-available/ge.conf
|
||||||
|
if [ ! -h /etc/nginx/sites-enabled/ge.conf ]
|
||||||
|
then
|
||||||
|
# If the configuration file is not activated yet, activates it
|
||||||
|
ln -s /etc/nginx/sites-available/ge.conf /etc/nginx/sites-enabled/ge.conf
|
||||||
|
fi
|
||||||
|
rm -f /etc/nginx/sites-enabled/default # We do not need this
|
||||||
|
service nginx restart
|
||||||
|
|
||||||
|
# Daphne and the worker(s)
|
||||||
|
for service in {daphne,worker}.service
|
||||||
|
do
|
||||||
|
cp /vagrant/provisioning/$service /etc/systemd/system/$service
|
||||||
|
fill_template /etc/systemd/system/$service
|
||||||
|
systemctl enable $service
|
||||||
|
systemctl start $service
|
||||||
|
done
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
redis-cli CONFIG SET requirepass $REDIS_PASSWD
|
||||||
|
if [ ! $? ]
|
||||||
|
then
|
||||||
|
# In case the requirepass command failed, checks that it was because the
|
||||||
|
# password was already set *to the right value*.
|
||||||
|
redis-cli AUTH $REDIS_PASSWD
|
||||||
|
fi
|
||||||
|
redis-cli -a $REDIS_PASSWD CONFIG REWRITE
|
||||||
|
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Prepare Django
|
||||||
|
# ---
|
||||||
|
|
||||||
|
cd /vagrant
|
||||||
|
|
||||||
|
# Setup the secrets
|
||||||
|
sudo -H -u vagrant cp evenementiel/settings/secret_example.py \
|
||||||
|
evenementiel/settings/secret.py
|
||||||
|
fill_template evenementiel/settings/secret.py
|
||||||
|
|
||||||
|
# Run the usual django admin commands
|
||||||
|
function venv_python {
|
||||||
|
sudo -H -u vagrant DJANGO_SETTINGS_MODULE=$SETTINGS \
|
||||||
|
~vagrant/venv/bin/python \
|
||||||
|
$@
|
||||||
|
}
|
||||||
|
|
||||||
|
venv_python manage.py collectstatic --noinput
|
||||||
|
venv_python manage.py migrate
|
||||||
|
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Setup a friendly environment for the user
|
||||||
|
# ---
|
||||||
|
|
||||||
cat > ~vagrant/.bash_profile <<EOF
|
cat > ~vagrant/.bash_profile <<EOF
|
||||||
# On utilise la version de prod de qwann.fr
|
# Use the .bashrc file provided by Debian
|
||||||
export DJANGO_SETTINGS_MODULE='evenementiel.settings_dev'
|
source .bashrc
|
||||||
|
|
||||||
# Identifiants MySQL
|
# Use the development settings
|
||||||
export DBUSER="$DBUSER"
|
export DJANGO_SETTINGS_MODULE="$SETTINGS"
|
||||||
export DBNAME="$DBNAME"
|
|
||||||
export DBPASSWD="$DBPASSWD"
|
|
||||||
|
|
||||||
# On va dans /vagrant où se trouve le code
|
# Move to the code's folder
|
||||||
cd /vagrant
|
cd /vagrant
|
||||||
|
|
||||||
|
# Activate the virtualenv
|
||||||
|
source ~vagrant/venv/bin/activate
|
||||||
EOF
|
EOF
|
||||||
chown vagrant: ~vagrant/.bash_profile
|
chown vagrant: ~vagrant/.bashrc
|
||||||
|
|
||||||
# On va dans /vagrant où se trouve le code
|
|
||||||
cd /vagrant
|
|
||||||
|
|
||||||
# Installation des dépendances python
|
|
||||||
sudo -H pip3 install -U pip
|
|
||||||
sudo -H -u vagrant pip3 install --user -r requirements.txt
|
|
||||||
sudo -H -u vagrant pip3 install --user -r requirements-devel.txt
|
|
||||||
|
|
||||||
# Préparation de Django
|
|
||||||
sudo -H -u vagrant DJANGO_SETTINGS_MODULE='evenementiel.settings_dev' DBUSER=$DBUSER DBNAME=$DBNAME DBPASSWD=$DBPASSWD python3 manage.py migrate
|
|
||||||
|
|
16
provisioning/daphne.service
Normal file
16
provisioning/daphne.service
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
Description="Gestion Événementiel - Daphne"
|
||||||
|
After=syslog.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=vagrant
|
||||||
|
Group=vagrant
|
||||||
|
TimeoutSec=300
|
||||||
|
WorkingDirectory=/vagrant
|
||||||
|
Environment="DJANGO_SETTINGS_MODULE={{SETTINGS}}"
|
||||||
|
ExecStart=/home/vagrant/venv/bin/daphne -u /srv/GE/GE.sock \
|
||||||
|
evenementiel.asgi:channel_layer
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
40
provisioning/nginx.conf
Normal file
40
provisioning/nginx.conf
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
upstream GE {
|
||||||
|
# Daphne listens on a unix socket
|
||||||
|
server unix:/srv/GE/GE.sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
# All the trafic is routed to Daphne
|
||||||
|
location ~ ^/ {
|
||||||
|
# A copy-paste of what we have in production
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-SSL-Client-Serial $ssl_client_serial;
|
||||||
|
proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
|
||||||
|
proxy_set_header X-SSL-Client-S-DN $ssl_client_s_dn;
|
||||||
|
# Reverse-proxy
|
||||||
|
proxy_pass http://GE;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static files
|
||||||
|
location ~ ^/static/ {
|
||||||
|
root /srv/GE/static/;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
expires 7d;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Uploaded media
|
||||||
|
location ~ ^/media/ {
|
||||||
|
root /srv/GE/static/;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
expires 7d;
|
||||||
|
}
|
||||||
|
}
|
16
provisioning/worker.service
Normal file
16
provisioning/worker.service
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[Unit]
|
||||||
|
Description="Gestion Événementiel - Worker"
|
||||||
|
After=syslog.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=vagrant
|
||||||
|
Group=vagrant
|
||||||
|
TimeoutSec=300
|
||||||
|
WorkingDirectory=/vagrant
|
||||||
|
Environment="DJANGO_SETTINGS_MODULE={{SETTINGS}}"
|
||||||
|
ExecStart=/home/vagrant/venv/bin/python manage.py runworker
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -1,2 +1,4 @@
|
||||||
|
-r requirements.txt
|
||||||
django-debug-toolbar
|
django-debug-toolbar
|
||||||
|
django-debug-panel
|
||||||
ipython
|
ipython
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
Django==1.11.*
|
Django==1.11.*
|
||||||
Pillow==3.3.0
|
psycopg2
|
||||||
psycopg2==2.6.2
|
asgi-redis
|
||||||
|
Pillow
|
||||||
|
channels
|
||||||
django-bootstrap-form==3.2.1
|
django-bootstrap-form==3.2.1
|
||||||
django-widget-tweaks
|
django-widget-tweaks
|
||||||
|
|
||||||
|
# Production specific
|
||||||
|
daphne
|
||||||
|
|
|
@ -1,3 +1,34 @@
|
||||||
from django.test import TestCase
|
from django.test import TestCase, Client
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
# Create your tests here.
|
|
||||||
|
class TestUserCreation(TestCase):
|
||||||
|
def test_create_view(self):
|
||||||
|
"""Create a user using the user creation form"""
|
||||||
|
user_data = {
|
||||||
|
"username": "MrsFoobar",
|
||||||
|
"first_name": "Baz",
|
||||||
|
"last_name": "Foobar",
|
||||||
|
"email": "baz@foobar.net",
|
||||||
|
}
|
||||||
|
|
||||||
|
data = user_data.copy()
|
||||||
|
data["password1"] = "4zwY5jdI"
|
||||||
|
data["password2"] = "4zwY5jdI"
|
||||||
|
data["key"] = settings.CREATE_USER_KEY
|
||||||
|
|
||||||
|
client = Client()
|
||||||
|
resp = client.post("/user/create/", data)
|
||||||
|
|
||||||
|
# The user redirection means successful form validation
|
||||||
|
self.assertRedirects(resp, "/")
|
||||||
|
|
||||||
|
# The user should now exist
|
||||||
|
user = (
|
||||||
|
User.objects
|
||||||
|
.filter(username=data["username"])
|
||||||
|
.values(*user_data.keys())
|
||||||
|
.get()
|
||||||
|
)
|
||||||
|
self.assertEqual(user_data, user)
|
||||||
|
|
Loading…
Reference in a new issue