Commit d0cf604a authored by Bonnegent Sebastien's avatar Bonnegent Sebastien
Browse files

cours 5 ok

parent 600f4067
% Django par la pratique #05
% Sébastien Bonnegent
% https://framagit.org/bonnegent/cours\_django
# Objectifs
## Ce qui est déjà fait
### Prérequis
* afficher la liste des ports
* afficher la liste des services
* afficher la liste des parefeux
* afficher un parefeu
## À faire
### Les formulaires
* de contact pour demander l'ajout d'un service
* d'ajout d'un parefeu
* de modification d'un parefeu
* d'ajout de règle dans un parefeu
* de modification de règle dans un parefeu
## À quoi ça peut ressembler #1
### Liste des parefeux
\center\includegraphics[height=4.5cm]{supports_cours_05/parefeu_list.png}
## À quoi ça peut ressembler #2
### Détail d'un parefeu
\center\includegraphics[height=4.5cm]{supports_cours_05/parefeu_detail.png}
## À quoi ça peut ressembler #3
### Liste des règles
\center\includegraphics[height=4.5cm]{supports_cours_05/regle_list.png}
## Comment faire ?
### Ressources
* https://docs.djangoproject.com/fr/1.11/
* supports\_cours\_05/debut: version du projet avant le TP
* supports\_cours\_05/fin: version du projet après le TP
# Modifications
## Simplification
### Modification des objets
* suppression de Modele
* le modèle (optionnel) d'un parefeu devient un parefeu
# À faire
## Ordre conseillé #1
### formulaire de contact
* https://docs.djangoproject.com/fr/1.11/topics/forms/
* webui/views.py
* webui/urls.py
* webui/templates/webui/service\_list.html
## Ordre conseillé #2
### formulaire d'ajout d'un parefeu
* https://docs.djangoproject.com/fr/1.11/topics/forms/modelforms/
* webui/forms.py
* webui/views.py
* webui/templates/webui/parefeu\_form\_create.html
* webui/urls.py
## Ordre conseillé #3
### formulaire de modification d'un parefeu (Modèle)
* https://docs.djangoproject.com/fr/1.11/topics/forms/modelforms/
* webui/views.py
* webui/templates/webui/parefeu\_form.html
* webui/urls.py
## Ordre conseillé #4
### afficher les règles sur la page de détail du parefeu
* webui/templates/webui/parefeu\_detail.html
## Ordre conseillé #5
### si modèle défini, afficher les règles du modèle
* webui/templates/webui/parefeu\_detail.html
## Ordre conseillé #6
### permettre l'édition des règles du parefeu
* ajout
* changer la priorité
* changer le status actif
* supprimer une règle (seulement si inactive)
### fichiers concernés
* https://docs.djangoproject.com/fr/1.11/topics/forms/modelforms/
* webui/templates/webui/regle\_list.html
* webui/forms.py
* webui/models.py
* webui/urls.py
## Ordre conseillé #7
### ajuster les autorisations de modification (admin + superuser)
* webui/urls.py
* webui/models.py
* webui/views.py
% version 2018
# Prérequis
## Base de départ
### Virtual Env
* source /opt/venv/django/bin/activate
* pipenv shell
### Sources
~~~
$ #!! settings.py et db.sqlite3 dans le dépôt !!
$ git clone \
https://gitlab.insa-rouen.fr/bonnegent/vehicules.git
$ cd vehicules
$ git checkout cours_5_debut
~~~
# Visibilité d'un véhicule
## Inclusion de templates
### garage/templates/garage/vehicule_list.html
~~~
<td>{% include 'garage/object_visible.html'
with object=vehicule only %}</td>
~~~
### garage/templates/garage/object_visible.html
~~~
{% if object.visible %}
<i class="fas fa-check"></i>
{% else %}
<i class="fas fa-ban"></i>
{% endif %}
~~~
### FontAwesome
* https://fontawesome.com/icons?d=gallery&m=free
## Messages #1
### garage/templates/garage/home.html
~~~
<div class="container-fluid">
{% for message in messages %}
{% if message.tags == "error" %}
<div class="alert alert-danger" role="alert">
{% else %}
<div class="alert alert-{{ message.tags }}"
role="alert">
{% endif %}
{{ message }}</div>
{% endfor %}
~~~
## Messages #2
### garage/views.py
~~~
from django.contrib import messages
messages.debug(request, "....")
messages.info(request, "....")
messages.success(request, "....")
messages.warning(request, "....")
messages.error(request, "....")
~~~
## Visibilité #1
### garage/views.py
~~~python
from django.shortcuts import redirect
from django.shortcuts import get_object_or_404
def vehicule_visible(request, pk):
vehicule = get_object_or_404(Vehicule, pk=pk)
if request.user == vehicule.proprietaire:
vehicule.toggle_visible()
messages.success(request,
"Modification enregistrée")
else:
messages.error(request, "Accès non autorisé")
return redirect('garage:vehicule-detail', pk)
~~~
## Visibilité #2
### garage/models.py
~~~python
import logging
LOG = logging.getLogger(__name__)
class Vehicule(...
def toggle_visible(self):
self.visible = not self.visible
LOG.info(f"changement état {self.id}:"
" {self.visible}")
self.save()
~~~
## Visibilité #3
### garage/urls.py
~~~python
path('vehicule/<int:pk>/visible/',
login_required(views.vehicule_visible),
name='vehicule-visible'),
~~~
### garage/templates/garage/vehicule_detail.html
~~~
<tr><td>Visible ?</td>
<td><a href="{% url 'garage:vehicule-visible'
vehicule.pk %}">
{% include 'garage/object_visible.html'
with object=vehicule only %}</a></td>
</tr>
~~~
## Visibilité #4
Les logs ne s'affichent pas ?
. . .
### supports_cours_05/settings.py
~~~python
...
"loggers": {
"django": {
"handlers": ["syslog", "console"],
"level": "INFO",
"propagate": True,
},
"garage": {"handlers": ["syslog", "console"],
"level": "DEBUG", "propagate": True},
},
~~~
# Formulaire de contact
## Classe de formulaire #1
### garage/forms.py
~~~python
from django import forms
class ContactForm(forms.Form):
sujet = forms.CharField()
message = forms.CharField(widget=forms.Textarea)
~~~
### garage/views.py
~~~python
from .forms import ContactForm
from django.views.generic.edit import FormView
from django.core.mail import send_mail
~~~
## Classe de formulaire #2
### garage/views.py
~~~python
class ContactView(FormView):
template_name = 'garage/contact.html'
form_class = ContactForm
success_url = reverse_lazy('garage:home')
def form_valid(self, form):
sujet = form.cleaned_data['sujet']
message = form.cleaned_data['message']
send_mail(sujet, message,
self.request.user.email,
['admin@example.com'])
return super().form_valid(form)
~~~
## Classe de formulaire #3
### garage/templates/garage/contact.html
~~~
{% extends "garage/home.html" %}
{% block content %}
<h2>Contact</h2>
<form method="post">{% csrf_token %}
<table>{{form.as_table}}
<td colspan=2>
<button class="btn btn-primary btn-block"
type="submit"/>Envoyer la demande</button>
</td>
</tr></table></form>
{% endblock %}
~~~
## Classe de formulaire #4
### garage/urls.py
~~~python
path('contact/',
login_required(views.ContactView.as_view()),
name='contact'),
~~~
## SMTP
### conf/settings.py
~~~python
EMAIL_HOST = 'localhost'
EMAIL_PORT = '1025'
~~~
### Serveur smtpd
~~~
python -m smtpd -n -c DebuggingServer localhost:1025
~~~
# Hijack
## Activation #1
### conf/settings.py
~~~python
HIJACK_LOGIN_REDIRECT_URL = '/'
HIJACK_LOGOUT_REDIRECT_URL = '/admin/auth/user/'
HIJACK_USE_BOOTSTRAP = True
HIJACK_ALLOW_GET_REQUESTS = True
INSTALLED_APPS = [ ...
'hijack',
'hijack_admin',
'compat',
~~~
## Activation #1
### conf/urls.py
~~~python
path('hj/', include('hijack.urls', namespace='hijack')),
~~~
### garage/templates/garage/home.html
~~~
{% load hijack_tags %}
...
<div class="container-fluid">
{% hijack_notification %}
{% block content %}
~~~
No preview for this file type
{% load staticfiles %}
<!DOCTYPE html>
<html lang="fr">
<head>
<link rel="shortcut icon" href="{% static 'webui/images/favicon.ico' %}"/>
<title>FWM</title>
</head>
<body>
{# Load the tag library #}
{% load bootstrap3 %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript %}
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
{# La barre de navigation #}
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a href="{% url 'index' %}" class="navbar-brand">FWM</a>
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#navbar-main">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="navbar-main">
{% if user.is_authenticated %}
<ul class="nav navbar-nav">
{% if user.is_staff %}
<li><a href="/admin/">Administration</a></li>
{% endif %}
<li><a href="/docs/">Documentation</a></li>
<li><a href="{% url 'parefeux' %}">Parefeux</a></li>
<li><a href="{% url 'modeles' %}">Modèles</a></li>
<li><a href="{% url 'services' %}">Services</a></li>
<li><a href="{% url 'ports' %}">Ports</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'logout' %}">
<span class="glyphicon glyphicon-remove-circle"></span>
</a></li>
</ul>
{% else %}
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'login' %}">
<span class="glyphicon glyphicon-log-in"></span>
Connexion</a></li>
</ul>
{% endif %}
</div>
</div>
</div>
<div class="container">
<div class="page-header" id="banner">
<div class="row">
<h1>{% block title %}Accueil{% endblock %}</h1>
</div>
</div>
{% block content %}
<p>Texte d'accueil par défaut.</p>
{% endblock %}
</div>
</body>
</html>
{% extends "webui/base.html" %}
{% block title %}Modèle: {{modele.nom}}{% endblock %}
{% block content %}
<table class="table table-striped">
<tr>
<th>Description</th>
<td>{{modele.description}}</td>
</tr>
<tr>
<th>Dernière modification</th>
<td>{{modele.modification}}</td>
</tr>
</table>
<h2>Liste des règles</h2>
{% include "webui/regle_list.html" with regle_list=modele.regles.all only %}
{% endblock %}
{% extends "webui/base.html" %}
{% block title %}Liste des modèles{% endblock %}
{% block content %}
<table class="table table-striped">
<tr>
<th>Nom</th>
<th>Nombre de règles</th>
<th>Dernière modification</th>
</tr>
{% for mod in modele_list %}
<tr>
<td><a href="{% url 'modele' mod.id %}">{{ mod }}</a></td>
<td>{{ mod.nombre_de_regles }}</td>
<td>{{ mod.modification }}</td>
</tr>
{% empty %}
<tr>
<td colspan=3>aucun modèle</td>
</tr>
{% endfor %}
<tr>
<th>Nom</th>
<th>Nombre de règles</th>
<th>Dernière modification</th>
</tr>
</table>
{% endblock %}
{% extends "webui/base.html" %}
{% block title %}Liste des parefeux{% endblock %}
{% block content %}
<table class="table table-striped">
<tr>
<th>Nom</th>
<th>Modèle</th>
<th>Nombre de règles</th>
<th>Administrateur</th>
<th>Dernière modification</th>
</tr>
{% for fw in parefeu_list %}
<tr>
<td>{{ fw }}</td>
<td><a href="{% url 'modele' fw.modele_id %}">{{ fw.modele }}</a></td>
<td>{{ fw.nombre_de_regles }}</td>
<td>{{ fw.admin }}</td>
<td>{{ fw.modification }}</td>
</tr>
{% empty %}
<tr>
<td colspan=5>aucun parefeu</td>
</tr>
{% endfor %}
<tr>
<th>Nom</th>
<th>Modèle</th>
<th>Nombre de règles</th>
<th>Administrateur</th>
<th>Dernière modification</th>
</tr>
<tr>
<td colpan=3 class="text-center">
<a class="btn btn-success" href="" role="button">Créer un parefeu</a>
</td>
<td colpan=2></td>
</tr>
</table>
{% endblock %}
{% extends "webui/base.html" %}
{% block title %}Liste des ports{% endblock %}
{% block content %}
<table class="table table-striped">
<tr>
<th>Protocole</th>
<th>Début</th>
<th>Fin</th>
</tr>
{% for port in port_list %}
<tr>
<td>{{ port.protocole }}</td>
<td>{{ port.debut }}</td>
<td>{{ port.fin }}</td>
</tr>
{% empty %}
<tr>
<td colspan=3>aucun port configuré</td>
</tr>
{% endfor %}
<tr>
<th>Protocole</th>
<th>Début</th>
<th>Fin</th>
</tr>
</table>
{% endblock %}
{% block content %}
<table class="table table-striped">
<tr>
<th>priorite</th>
<th>groupe</th>
<th>services</th>
<th>interface</th>
<th>actif</th>
<th>sens</th>
</tr>
{% for regle in regle_list %}
<tr>
<th>{{regle.priorite}}</th>
<th>{% if regle.groupe %}{{regle.groupe}}{% endif %}</th>
<th>{{regle.liste_des_services}}</th>
<th>{{regle.interface}}</th>
<th>{% if regle.actif %}
<span class="glyphicon glyphicon-ok-circle"></span>
{% else %}
<span class="glyphicon glyphicon-ban-circle"></span>
{% endif %}</th>
<th>{{regle.get_sens_display}}</th>
</tr>
{% empty %}
<tr>
<td colspan=6>aucune règle</td>
</tr>
{% endfor %}
</table>
{% endblock %}
{% extends "webui/base.html" %}
{% block title %}Liste des services{% endblock %}
{% block content %}
<table class="table table-striped">
<tr>
<th>Nom</th>
<th>Liste des ports</th>
</tr>
{% for svc in service_list %}
<tr>
<td>{{ svc }}</td>
<td>{{ svc.liste_des_ports }}</td>
</tr>
{% empty %}
<tr>
<td colspan=2>aucun service configuré</td>
</tr>
{% endfor %}
<tr>
<th>Nom</th>
<th>Liste des ports</th>
</tr>
</table>
{% endblock %}
{% load staticfiles %}
<!DOCTYPE html>
<html lang="fr">
<head>
<link rel="shortcut icon" href="{% static 'webui/images/favicon.ico' %}"/>
<title>FWM</title>
</head>
<body>
<script type="text/javascript" src="{% static 'webui/js/jquery-3.2.1.min.js' %}"></script>
{# Load the tag library #}
{% load bootstrap3 %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript %}
<link rel="stylesheet" href="{% static 'webui/DataTables-1.10.16/css/dataTables.bootstrap.css' %}">
<script type="text/javascript" src="{% static 'webui/DataTables-1.10.16/js/jquery.dataTables.js' %}"></script>
<script type="text/javascript" src="{% static 'webui/DataTables-1.10.16/js/dataTables.bootstrap.js' %}"></script>
{# Display django.contrib.messages as Bootstrap alerts #}
{% bootstrap_messages %}
{# La barre de navigation #}
<div class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a href="{% url 'parefeux' %}" class="navbar-brand">FWM</a>
<button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#navbar-main">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="navbar-main">
{% if user.is_authenticated %}
<ul class="nav navbar-nav">
{% if user.is_staff %}
<li><a href="/admin/">Administration</a></li>
{% endif %}
<li><a href="/docs/">Documentation</a></li>
<li><a href="{% url 'modeles' %}">Modèles</a></li>
<li><a href="{% url 'parefeux' %}">Parefeux</a></li>
<li><a href="{% url 'services' %}">Services</a></li>
<li><a href="{% url 'ports' %}">Ports</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'logout' %}">
<span class="glyphicon glyphicon-remove-circle"></span>
</a></li>
</ul>
{% else %}
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'login' %}">
<span class="glyphicon glyphicon-log-in"></span>
Connexion</a></li>
</ul>
{% endif %}
</div>