Djadhere » Historique » Version 10
Version 9 (Matthieu Herrb, 26/05/2022 11:37) → Version 10/11 (Matthieu Herrb, 26/05/2022 11:38)
h1. Djadhere
C’est le SI de tetaneutral.net ! Il est codé en Python avec le framework web Django.
Il est accessible à l’adresse https://adhesions.tetaneutral.net.
h2. Contribuer
Le code source est sur la forge de ffdn : https://code.ffdn.org/tetaneutral.net/djadhere
Celle-ci permet également d’ouvrir des tickets ou de créer des pull-requests.
Pour rejoindre l’équipe, demander à djanos ou nim65s sur IRC.
Pad de travail : http://pad.tetaneutral.net/p/djadhere
Pad : http://pad.tetaneutral.net/p/web
Liste : https://lists.tetaneutral.net/listinfo/projet-web
h2. Utilisation
h3. Ligne de commande
Accès au @manage.py@ :
@# ./go-prod.sh
$ cd app
$ ./manage.py@
Création d’un super utilisateur :
@$ ./manage.py createsuperuser@
Statistiques financières des services :
@$ ./manage.py servicesstats@
h3. Interface django admin
Accès : https://adhesions.tetaneutral.net/admin/ https://adherents.tetaneutral.net/admin/
h4. Comptes de tests
Différents comptes de tests sont disponibles pour tester les fonctionnalités en tant que membre d’équipage pour un service donnée ou responsable banquaire.
Les logins et mots de passe sont disponibles dans le fichier 'password.txt' présent dans le home de l’utilisateur django-prod.
h4. Création d’un nouveau type de service et délégation de sa gestion
* Créer un groupe « equipage-toulouse » par exemple
* Créer un nouveau type de service « Abo Toulouse » par exemple, et définir le groupe « equipage-toulouse » comme groupe de gestion
* Dans le profil des utilisateurs gestionnaires :
* Cocher « Statut équipe » pour lui permettre de se connecter à l’interface d’administration
* L’ajouter au groupe « equipage-toulouse » pour lui donner les droits nécessaires
* Créer un ou des services de type « Abo Toulouse » en configurant la / les IP associé(s) mais sans spécifier d’adhérent.
h4. Gestion d’un service par un membre d’une équipe
Un utilisateur appartenant à un équipage peut :
* Consulter les utilisateurs, modifier leur nom, prénom, adresse emails, numéro de téléphone et adresse.
* Définir comme adhérent un utilisateur et ainsi lui obtenir un numéro d’adhérent.
* Consulter les adhérent·es (utilisateur·rice adhérents (utilisateur ou personne morale) et ajouter une cotisation.
Une cotisation reste modifiable ou supprimable jusqu’à validation par l’équipage « banque ».
* Consulter les services des types correspondant aux groupes de gestion auquel l’utilisateur appartient.
* Modifier les services : adhérent, date de début, date de fin et paiements liés au service.
Les paiements sont modifiable et supprimable jusqu’à validation par l’équipage « banque ».
h4. Configuration d’un équipage « banque »
* Créer un groupe « equipage-banque » et lui donner les 4 permissions « banking | paiement » : add / change / delete / validate.
* Éditer les utilisateurs voulus et les ajouter au groupe « equipage-banque ».
h4. Gestion des paiements par l’équipage « banque »
Un utilisateur avec les permissions « banking | paiement » peut consulter et modifier l’ensemble des paiements.
Il peut en particulier les valider ; ceux-ci ne sont alors plus modifiable par les membres d’équipage « services ».
FIXME: Il n’y a pour le moment aucun stoquage des coordonnées banquaires.
h2. Déploiement
Il est déployé sur la VM djadhere.tetaneutral.net (Debian 8.6 Jessie).
Deux instances sont déployées, la première pour la version de production, et la deuxième pour la version de developpement.
Le serveur web utilisé est nginx.
La configuration se trouve dans le fichier @/etc/nginx/sites-available/djadhere@.
Les certificats letsencrypt sont généré avec @certbot@ (installé depuis les backports) :
@certbot -c /etc/letsencrypt/webroot.ini -d mondomaine.tetaneutral.net@
La base de données utilisée est postgresql.
Django est lancé par @uwsgi@.
La configuration de celui-ci se trouve dans le dossier @/etc/uwsgi/@.
Les dossiers @apps-available@ et @apps-enabled@ ne sont pas utilisé.
En effet, l’ajout du .service systemd uwsgi@.service permet de lancer de manière indépendante chaque instance.
Voici une description du déploiement de la prod, le déploiement en dev étant analogue.
Le dossier @/etc/uwsgi/djadhere/@ contient un lien symbolique vers la configuration uwsgi de cette instance.
Le lien est nommé @prod@ permettant d’utiliser systemd ainsi :
@systemctl {start,stop,restart,status} uwsgi@djadhere-prod@
Un utilisateur @djadhere-prod@ a été créé (et automatiquement un groupe du même nom).
L’utilisateur @www-data@ a été rajouté au groupe @djadhere-prod@.
L’umask de @djadhere-prod@ est définie à 077 dans son @.bashrc@.
Le home de djadhere-prod se trouve dans le dossier @/srv/djadhere/prod@ et contient :
* @uwsgi.ini@ : la conf uwsgi symlinké depuis @/etc/uwsgi/djadhere/prod@
* @uwsgi.socket@ : le socket unix référencé dans la conf de nginx
* @touch-to-reload@ : un fichier permettant de relancer uwsgi via la commande touch : @touch touch-to-reload@
* @app@ : un clone du projet Git
* @log@ : les logs (nginx + uwsgi + django)
* @venv@ : le virtualenv dans lequel tourne django
* @webdir@ : le dossier servie par nginx (g+rX) qui contient un dossier static et un dossier media (géré par django)
* @update.sh@ : un script pour mettre à jour
Voici la conf uwsgi.ini :
<pre>
[uwsgi]
uid = djadhere-prod
gid = djadhere-prod
chdir = /srv/djadhere/prod/app
plugin=python3
module=djadhere.wsgi:application
virtualenv = /srv/djadhere/prod/venv
env=DJANGO_SETTINGS_MODULE=djadhere.local_settings
uwsgi-socket=/srv/djadhere/prod/uwsgi.socket
chmod-socket=660
pidfile=/srv/djadhere/prod/uwsgi.pid
touch-reload = /srv/djadhere/prod/touch-to-reload
logto=/srv/djadhere/prod/log/uwsgi.log
logfile-chmod=400
logfile-chown=djadhere-prod:djadhere-prod
vacuum=True
</pre>
Voici une partie de la configuration local de django (situé dans @app/djadhere/local_settings.py@) :
<pre>
from djadhere.settings import *
from os.path import join
BASE_DIR = '/srv/djadhere/prod/'
SECRET_KEY = 'removed'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'djadhere_prod',
'USER': 'djadhere_prod',
'PASSWORD': 'removed',
'HOST': 'localhost',
'PORT': '',
},
}
DEBUG = False
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'WARNING',
'class': 'logging.FileHandler',
'filename': join(BASE_DIR, 'log/debug.log'),
},
'mail_admins': {
'class': 'django.utils.log.AdminEmailHandler',
'level': 'ERROR',
# But the emails are plain text by default - HTML is nicer
'include_html': True,
},
},
'loggers': {
'django.request': {
'handlers': ['file', 'mail_admins'],
'level': 'WARNING',
'propagate': True,
},
},
}
STATIC_ROOT = join(BASE_DIR, 'webdir/static')
STATIC_URL = '/static/'
MEDIA_ROOT = join(BASE_DIR, 'webdir/media')
MEDIA_URL = '/media/'
ALLOWED_HOSTS = [ 'adherents.tetaneutral.net' ]
DEFAULT_FROM_EMAIL = 'noreply@tetaneutral.net'
SERVER_EMAIL = 'djadhere <projet-web-at-lists.tetaneutral.net>'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp'
EMAIL_SUBJECT_PREFIX = "[PROD] "
ADMINS = (
('Prénom Nom', 'adresse mail'),
)
</pre>
Et le script d’easy update :
<pre>
#!/bin/bash
cd ~/app
git fetch
git checkout master
pip install --upgrade -r requirements.txt
./manage.py migrate
./manage.py collectstatic --noinput
cd ~
chmod g+rX webdir -R
touch touch-to-reload
</pre>
C’est le SI de tetaneutral.net ! Il est codé en Python avec le framework web Django.
Il est accessible à l’adresse https://adhesions.tetaneutral.net.
h2. Contribuer
Le code source est sur la forge de ffdn : https://code.ffdn.org/tetaneutral.net/djadhere
Celle-ci permet également d’ouvrir des tickets ou de créer des pull-requests.
Pour rejoindre l’équipe, demander à djanos ou nim65s sur IRC.
Pad de travail : http://pad.tetaneutral.net/p/djadhere
Pad : http://pad.tetaneutral.net/p/web
Liste : https://lists.tetaneutral.net/listinfo/projet-web
h2. Utilisation
h3. Ligne de commande
Accès au @manage.py@ :
@# ./go-prod.sh
$ cd app
$ ./manage.py@
Création d’un super utilisateur :
@$ ./manage.py createsuperuser@
Statistiques financières des services :
@$ ./manage.py servicesstats@
h3. Interface django admin
Accès : https://adhesions.tetaneutral.net/admin/ https://adherents.tetaneutral.net/admin/
h4. Comptes de tests
Différents comptes de tests sont disponibles pour tester les fonctionnalités en tant que membre d’équipage pour un service donnée ou responsable banquaire.
Les logins et mots de passe sont disponibles dans le fichier 'password.txt' présent dans le home de l’utilisateur django-prod.
h4. Création d’un nouveau type de service et délégation de sa gestion
* Créer un groupe « equipage-toulouse » par exemple
* Créer un nouveau type de service « Abo Toulouse » par exemple, et définir le groupe « equipage-toulouse » comme groupe de gestion
* Dans le profil des utilisateurs gestionnaires :
* Cocher « Statut équipe » pour lui permettre de se connecter à l’interface d’administration
* L’ajouter au groupe « equipage-toulouse » pour lui donner les droits nécessaires
* Créer un ou des services de type « Abo Toulouse » en configurant la / les IP associé(s) mais sans spécifier d’adhérent.
h4. Gestion d’un service par un membre d’une équipe
Un utilisateur appartenant à un équipage peut :
* Consulter les utilisateurs, modifier leur nom, prénom, adresse emails, numéro de téléphone et adresse.
* Définir comme adhérent un utilisateur et ainsi lui obtenir un numéro d’adhérent.
* Consulter les adhérent·es (utilisateur·rice adhérents (utilisateur ou personne morale) et ajouter une cotisation.
Une cotisation reste modifiable ou supprimable jusqu’à validation par l’équipage « banque ».
* Consulter les services des types correspondant aux groupes de gestion auquel l’utilisateur appartient.
* Modifier les services : adhérent, date de début, date de fin et paiements liés au service.
Les paiements sont modifiable et supprimable jusqu’à validation par l’équipage « banque ».
h4. Configuration d’un équipage « banque »
* Créer un groupe « equipage-banque » et lui donner les 4 permissions « banking | paiement » : add / change / delete / validate.
* Éditer les utilisateurs voulus et les ajouter au groupe « equipage-banque ».
h4. Gestion des paiements par l’équipage « banque »
Un utilisateur avec les permissions « banking | paiement » peut consulter et modifier l’ensemble des paiements.
Il peut en particulier les valider ; ceux-ci ne sont alors plus modifiable par les membres d’équipage « services ».
FIXME: Il n’y a pour le moment aucun stoquage des coordonnées banquaires.
h2. Déploiement
Il est déployé sur la VM djadhere.tetaneutral.net (Debian 8.6 Jessie).
Deux instances sont déployées, la première pour la version de production, et la deuxième pour la version de developpement.
Le serveur web utilisé est nginx.
La configuration se trouve dans le fichier @/etc/nginx/sites-available/djadhere@.
Les certificats letsencrypt sont généré avec @certbot@ (installé depuis les backports) :
@certbot -c /etc/letsencrypt/webroot.ini -d mondomaine.tetaneutral.net@
La base de données utilisée est postgresql.
Django est lancé par @uwsgi@.
La configuration de celui-ci se trouve dans le dossier @/etc/uwsgi/@.
Les dossiers @apps-available@ et @apps-enabled@ ne sont pas utilisé.
En effet, l’ajout du .service systemd uwsgi@.service permet de lancer de manière indépendante chaque instance.
Voici une description du déploiement de la prod, le déploiement en dev étant analogue.
Le dossier @/etc/uwsgi/djadhere/@ contient un lien symbolique vers la configuration uwsgi de cette instance.
Le lien est nommé @prod@ permettant d’utiliser systemd ainsi :
@systemctl {start,stop,restart,status} uwsgi@djadhere-prod@
Un utilisateur @djadhere-prod@ a été créé (et automatiquement un groupe du même nom).
L’utilisateur @www-data@ a été rajouté au groupe @djadhere-prod@.
L’umask de @djadhere-prod@ est définie à 077 dans son @.bashrc@.
Le home de djadhere-prod se trouve dans le dossier @/srv/djadhere/prod@ et contient :
* @uwsgi.ini@ : la conf uwsgi symlinké depuis @/etc/uwsgi/djadhere/prod@
* @uwsgi.socket@ : le socket unix référencé dans la conf de nginx
* @touch-to-reload@ : un fichier permettant de relancer uwsgi via la commande touch : @touch touch-to-reload@
* @app@ : un clone du projet Git
* @log@ : les logs (nginx + uwsgi + django)
* @venv@ : le virtualenv dans lequel tourne django
* @webdir@ : le dossier servie par nginx (g+rX) qui contient un dossier static et un dossier media (géré par django)
* @update.sh@ : un script pour mettre à jour
Voici la conf uwsgi.ini :
<pre>
[uwsgi]
uid = djadhere-prod
gid = djadhere-prod
chdir = /srv/djadhere/prod/app
plugin=python3
module=djadhere.wsgi:application
virtualenv = /srv/djadhere/prod/venv
env=DJANGO_SETTINGS_MODULE=djadhere.local_settings
uwsgi-socket=/srv/djadhere/prod/uwsgi.socket
chmod-socket=660
pidfile=/srv/djadhere/prod/uwsgi.pid
touch-reload = /srv/djadhere/prod/touch-to-reload
logto=/srv/djadhere/prod/log/uwsgi.log
logfile-chmod=400
logfile-chown=djadhere-prod:djadhere-prod
vacuum=True
</pre>
Voici une partie de la configuration local de django (situé dans @app/djadhere/local_settings.py@) :
<pre>
from djadhere.settings import *
from os.path import join
BASE_DIR = '/srv/djadhere/prod/'
SECRET_KEY = 'removed'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'djadhere_prod',
'USER': 'djadhere_prod',
'PASSWORD': 'removed',
'HOST': 'localhost',
'PORT': '',
},
}
DEBUG = False
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'WARNING',
'class': 'logging.FileHandler',
'filename': join(BASE_DIR, 'log/debug.log'),
},
'mail_admins': {
'class': 'django.utils.log.AdminEmailHandler',
'level': 'ERROR',
# But the emails are plain text by default - HTML is nicer
'include_html': True,
},
},
'loggers': {
'django.request': {
'handlers': ['file', 'mail_admins'],
'level': 'WARNING',
'propagate': True,
},
},
}
STATIC_ROOT = join(BASE_DIR, 'webdir/static')
STATIC_URL = '/static/'
MEDIA_ROOT = join(BASE_DIR, 'webdir/media')
MEDIA_URL = '/media/'
ALLOWED_HOSTS = [ 'adherents.tetaneutral.net' ]
DEFAULT_FROM_EMAIL = 'noreply@tetaneutral.net'
SERVER_EMAIL = 'djadhere <projet-web-at-lists.tetaneutral.net>'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp'
EMAIL_SUBJECT_PREFIX = "[PROD] "
ADMINS = (
('Prénom Nom', 'adresse mail'),
)
</pre>
Et le script d’easy update :
<pre>
#!/bin/bash
cd ~/app
git fetch
git checkout master
pip install --upgrade -r requirements.txt
./manage.py migrate
./manage.py collectstatic --noinput
cd ~
chmod g+rX webdir -R
touch touch-to-reload
</pre>