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
|
||||
# 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
|
||||
# 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
|
||||
# pour une installation de dév locale qui ne sera accessible que depuis la
|
||||
# machine virtuelle.
|
||||
# The credentials of the database. Can be public since they will only be used in
|
||||
# the local development environment
|
||||
DBUSER="event_gestion"
|
||||
DBNAME="event_gestion"
|
||||
DBPASSWD="4KZt3nGPLVeWSvtBZPsd9jdssdJMds78"
|
||||
|
||||
# Installation de paquets utiles
|
||||
apt-get update && apt-get install -y python3-pip python3-dev \
|
||||
libpq-dev postgresql postgresql-contrib libjpeg-dev
|
||||
# Not critical either
|
||||
REDIS_PASSWD="dummy"
|
||||
|
||||
# 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 createuser -SDR $DBUSER
|
||||
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 "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
|
||||
# On utilise la version de prod de qwann.fr
|
||||
export DJANGO_SETTINGS_MODULE='evenementiel.settings_dev'
|
||||
# Use the .bashrc file provided by Debian
|
||||
source .bashrc
|
||||
|
||||
# Identifiants MySQL
|
||||
export DBUSER="$DBUSER"
|
||||
export DBNAME="$DBNAME"
|
||||
export DBPASSWD="$DBPASSWD"
|
||||
# Use the development settings
|
||||
export DJANGO_SETTINGS_MODULE="$SETTINGS"
|
||||
|
||||
# On va dans /vagrant où se trouve le code
|
||||
# Move to the code's folder
|
||||
cd /vagrant
|
||||
|
||||
# Activate the virtualenv
|
||||
source ~vagrant/venv/bin/activate
|
||||
EOF
|
||||
chown vagrant: ~vagrant/.bash_profile
|
||||
|
||||
# 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
|
||||
chown vagrant: ~vagrant/.bashrc
|
||||
|
|
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-panel
|
||||
ipython
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
Django==1.11.*
|
||||
Pillow==3.3.0
|
||||
psycopg2==2.6.2
|
||||
psycopg2
|
||||
asgi-redis
|
||||
Pillow
|
||||
channels
|
||||
django-bootstrap-form==3.2.1
|
||||
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