diff --git a/freeradius_utils/auth.py b/freeradius_utils/auth.py
index ab10d457..3fa7e23f 100644
--- a/freeradius_utils/auth.py
+++ b/freeradius_utils/auth.py
@@ -57,14 +57,9 @@ application = get_wsgi_application()
from machines.models import Interface, IpList, Nas, Domain
from topologie.models import Port, Switch
from users.models import User
-from preferences.models import OptionalTopologie
+from preferences.models import RadiusOption
-options, created = OptionalTopologie.objects.get_or_create()
-VLAN_NOK = options.vlan_decision_nok.vlan_id
-VLAN_OK = options.vlan_decision_ok.vlan_id
-RADIUS_POLICY = options.radius_general_policy
-
#: Serveur radius de test (pas la prod)
TEST_SERVER = bool(os.getenv('DBG_FREERADIUS', False))
@@ -287,6 +282,7 @@ def find_nas_from_request(nas_id):
.select_related('machine__switch__stack'))
return nas.first()
+
def check_user_machine_and_register(nas_type, username, mac_address):
"""Verifie le username et la mac renseignee. L'enregistre si elle est
inconnue.
@@ -327,32 +323,50 @@ def check_user_machine_and_register(nas_type, username, mac_address):
def decide_vlan_switch(nas_machine, nas_type, port_number,
- mac_address):
+ mac_address):
"""Fonction de placement vlan pour un switch en radius filaire auth par
mac.
Plusieurs modes :
- - nas inconnu, port inconnu : on place sur le vlan par defaut VLAN_OK
- - pas de radius sur le port : VLAN_OK
- - bloq : VLAN_NOK
- - force : placement sur le vlan indiqué dans la bdd
- - mode strict :
- - pas de chambre associée : VLAN_NOK
- - pas d'utilisateur dans la chambre : VLAN_NOK
- - cotisation non à jour : VLAN_NOK
- - sinon passe à common (ci-dessous)
- - mode common :
- - interface connue (macaddress):
- - utilisateur proprio non cotisant ou banni : VLAN_NOK
- - user à jour : VLAN_OK
- - interface inconnue :
- - register mac désactivé : VLAN_NOK
- - register mac activé -> redirection vers webauth
+ - tous les modes:
+ - nas inconnu: VLAN_OK
+ - port inconnu: Politique définie dans RadiusOption
+ - pas de radius sur le port: VLAN_OK
+ - force: placement sur le vlan indiqué dans la bdd
+ - mode strict:
+ - pas de chambre associée: Politique définie
+ dans RadiusOption
+ - pas d'utilisateur dans la chambre : Rejet
+ (redirection web si disponible)
+ - utilisateur de la chambre banni ou désactivé : Rejet
+ (redirection web si disponible)
+ - utilisateur de la chambre non cotisant et non whiteslist:
+ Politique définie dans RadiusOption
+
+ - sinon passe à common (ci-dessous)
+ - mode common :
+ - interface connue (macaddress):
+ - utilisateur proprio non cotisant / machine désactivée:
+ Politique définie dans RadiusOption
+ - utilisateur proprio banni :
+ Politique définie dans RadiusOption
+ - user à jour : VLAN_OK (réassignation de l'ipv4 au besoin)
+ - interface inconnue :
+ - register mac désactivé : Politique définie
+ dans RadiusOption
+ - register mac activé: redirection vers webauth
+ Returns:
+ tuple avec :
+ - Nom du switch (str)
+ - chambre (str)
+ - raison de la décision (str)
+ - vlan_id (int)
+ - decision (bool)
"""
# Get port from switch and port number
extra_log = ""
# Si le NAS est inconnu, on place sur le vlan defaut
if not nas_machine:
- return ('?', u'Chambre inconnue', u'Nas inconnu', VLAN_OK, True)
+ return ('?', u'Chambre inconnue', u'Nas inconnu', RadiusOption.get_cached_value('vlan_decision_ok').vlan_id, True)
sw_name = str(getattr(nas_machine, 'short_name', str(nas_machine)))
@@ -367,7 +381,13 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
# Aucune information particulière ne permet de déterminer quelle
# politique à appliquer sur ce port
if not port:
- return (sw_name, "Chambre inconnue", u'Port inconnu', VLAN_OK, True)
+ return (
+ sw_name,
+ "Chambre inconnue",
+ u'Port inconnu',
+ RadiusOption('unknown_port_vlan').vlan_id,
+ RadiusOption('unknown_port')!= RadiusOption.REJECT
+ )
# On récupère le profil du port
port_profile = port.get_port_profile
@@ -378,11 +398,11 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
DECISION_VLAN = int(port_profile.vlan_untagged.vlan_id)
extra_log = u"Force sur vlan " + str(DECISION_VLAN)
else:
- DECISION_VLAN = VLAN_OK
+ DECISION_VLAN = RadiusOption.get_cached_value('vlan_decision_ok')
- # Si le port est désactivé, on rejette sur le vlan de déconnexion
+ # Si le port est désactivé, on rejette la connexion
if not port.state:
- return (sw_name, port.room, u'Port desactivé', VLAN_NOK, True)
+ return (sw_name, port.room, u'Port desactivé', None, False)
# Si radius est désactivé, on laisse passer
if port_profile.radius_type == 'NO':
@@ -392,33 +412,68 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
DECISION_VLAN,
True)
- # Si le 802.1X est activé sur ce port, cela veut dire que la personne a été accept précédemment
+ # Si le 802.1X est activé sur ce port, cela veut dire que la personne a
+ # été accept précédemment
# Par conséquent, on laisse passer sur le bon vlan
- if nas_type.port_access_mode == '802.1X' and port_profile.radius_type == '802.1X':
+ if (nas_type.port_access_mode, port_profile.radius_type) == ('802.1X', '802.1X'):
room = port.room or "Chambre/local inconnu"
- return (sw_name, room, u'Acceptation authentification 802.1X', DECISION_VLAN, True)
+ return (
+ sw_name,
+ room,
+ u'Acceptation authentification 802.1X',
+ DECISION_VLAN,
+ True
+ )
# Sinon, cela veut dire qu'on fait de l'auth radius par mac
# Si le port est en mode strict, on vérifie que tous les users
- # rattachés à ce port sont bien à jour de cotisation. Sinon on rejette (anti squattage)
- # Il n'est pas possible de se connecter sur une prise strict sans adhérent à jour de cotis
- # dedans
+ # rattachés à ce port sont bien à jour de cotisation. Sinon on rejette
+ # (anti squattage)
+ # Il n'est pas possible de se connecter sur une prise strict sans adhérent
+ # à jour de cotis dedans
if port_profile.radius_mode == 'STRICT':
room = port.room
if not room:
- return (sw_name, "Inconnue", u'Chambre inconnue', VLAN_NOK, True)
+ return (
+ sw_name,
+ "Inconnue",
+ u'Chambre inconnue',
+ RadiusOption('unknown_room_vlan').vlan_id,
+ RadiusOption('unknown_room')!= RadiusOption.REJECT
+ )
room_user = User.objects.filter(
Q(club__room=port.room) | Q(adherent__room=port.room)
)
if not room_user:
- return (sw_name, room, u'Chambre non cotisante -> Web redirect', None, False)
+ return (
+ sw_name,
+ room,
+ u'Chambre non cotisante -> Web redirect',
+ None,
+ False
+ )
for user in room_user:
- if not user.has_access():
- return (sw_name, room, u'Chambre resident desactive -> Web redirect', None, False)
+ if user.is_ban() or user.state != User.STATE_ACTIVE:
+ return (
+ sw_name,
+ room,
+ u'Utilisateur banni ou désactivé -> Web redirect',
+ None,
+ False
+ )
+ elif not (user.is_connected() or user.is_whitelisted()):
+ return (
+ sw_name,
+ room,
+ u'Utilisateur non cotisant',
+ RadiusOption('non_member_vlan').vlan_id,
+ RadiusOption('non_member')!= RadiusOption.REJECT
+ )
# else: user OK, on passe à la verif MAC
- # Si on fait de l'auth par mac, on cherche l'interface via sa mac dans la bdd
+ # Si on fait de l'auth par mac, on cherche l'interface
+ # via sa mac dans la bdd
if port_profile.radius_mode == 'COMMON' or port_profile.radius_mode == 'STRICT':
# Authentification par mac
interface = (Interface.objects
@@ -428,38 +483,67 @@ def decide_vlan_switch(nas_machine, nas_type, port_number,
.first())
if not interface:
room = port.room
- # On essaye de register la mac, si l'autocapture a été activée
- # Sinon on rejette sur vlan_nok
- if not nas_type.autocapture_mac:
- return (sw_name, "", u'Machine inconnue', VLAN_NOK, True)
- # On rejette pour basculer sur du webauth
+ # On essaye de register la mac, si l'autocapture a été activée,
+ # on rejette pour faire une redirection web si possible.
+ if nas_type.autocapture_mac:
+ return (
+ sw_name,
+ room,
+ u'Machine Inconnue -> Web redirect',
+ None,
+ False
+ )
+ # Sinon on bascule sur la politique définie dans les options
+ # radius.
else:
- return (sw_name, room, u'Machine Inconnue -> Web redirect', None, False)
+ return (
+ sw_name,
+ "",
+ u'Machine inconnue',
+ RadiusOption('unknown_machine_vlan').vlan_id,
+ RadiusOption('unknown_machine')!= RadiusOption.REJECT
+ )
- # L'interface a été trouvée, on vérifie qu'elle est active, sinon on reject
+ # L'interface a été trouvée, on vérifie qu'elle est active,
+ # sinon on reject
# Si elle n'a pas d'ipv4, on lui en met une
# Enfin on laisse passer sur le vlan pertinent
else:
room = port.room
+ if interface.machine.user.is_ban():
+ return (
+ sw_name,
+ room,
+ u'Adherent banni',
+ RadiusOption('banned_vlan').vlan_id,
+ RadiusOption('banned')!= RadiusOption.REJECT
+ )
if not interface.is_active:
- return (sw_name,
- room,
- u'Machine non active / adherent non cotisant',
- VLAN_NOK,
- True)
- ## Si on choisi de placer les machines sur le vlan correspondant à leur type :
- if RADIUS_POLICY == 'MACHINE':
+ return (
+ sw_name,
+ room,
+ u'Machine non active / adherent non cotisant',
+ RadiusOption('non_member_vlan').vlan_id,
+ RadiusOption('non_member')!= RadiusOption.REJECT
+ )
+ # Si on choisi de placer les machines sur le vlan
+ # correspondant à leur type :
+ if RadiusOption.get_cached_value('radius_general_policy') == 'MACHINE':
DECISION_VLAN = interface.type.ip_type.vlan.vlan_id
if not interface.ipv4:
interface.assign_ipv4()
- return (sw_name,
- room,
- u"Ok, Reassignation de l'ipv4" + extra_log,
- DECISION_VLAN,
- True)
+ return (
+ sw_name,
+ room,
+ u"Ok, Reassignation de l'ipv4" + extra_log,
+ DECISION_VLAN,
+ True
+ )
else:
- return (sw_name,
- room,
- u'Machine OK' + extra_log,
- DECISION_VLAN,
- True)
+ return (
+ sw_name,
+ room,
+ u'Machine OK' + extra_log,
+ DECISION_VLAN,
+ True
+ )
diff --git a/preferences/forms.py b/preferences/forms.py
index 2f90927f..1126b399 100644
--- a/preferences/forms.py
+++ b/preferences/forms.py
@@ -42,6 +42,7 @@ from .models import (
Reminder,
RadiusKey,
SwitchManagementCred,
+ RadiusOption,
)
from topologie.models import Switch
@@ -229,6 +230,13 @@ class EditHomeOptionForm(ModelForm):
self.fields['twitter_account_name'].label = _("Twitter account name")
+class EditRadiusOptionForm(ModelForm):
+ """Edition forms for Radius options"""
+ class Meta:
+ model = RadiusOption
+ fields = '__all__'
+
+
class ServiceForm(ModelForm):
"""Edition, ajout de services sur la page d'accueil"""
class Meta:
diff --git a/preferences/migrations/0055_generaloption_main_site_url.py b/preferences/migrations/0055_generaloption_main_site_url.py
index 71ea9852..655c0b07 100644
--- a/preferences/migrations/0055_generaloption_main_site_url.py
+++ b/preferences/migrations/0055_generaloption_main_site_url.py
@@ -8,7 +8,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('preferences', '0054_merge_20181025_1258'),
+ ('preferences', '0053_optionaluser_self_change_room'),
]
operations = [
diff --git a/preferences/migrations/0056_radiusoption.py b/preferences/migrations/0056_radiusoption.py
new file mode 100644
index 00000000..e329f598
--- /dev/null
+++ b/preferences/migrations/0056_radiusoption.py
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2018-10-13 14:29
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+import re2o.mixins
+
+
+def create_radius_policy(apps, schema_editor):
+ OptionalTopologie = apps.get_model('preferences', 'OptionalTopologie')
+ RadiusOption = apps.get_model('preferences', 'RadiusOption')
+
+ option,_ = OptionalTopologie.objects.get_or_create()
+
+ radius_option = RadiusOption()
+ radius_option.radius_general_policy = option.radius_general_policy
+ radius_option.vlan_decision_ok = option.vlan_decision_ok
+
+ radius_option.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('machines', '0095_auto_20180919_2225'),
+ ('preferences', '0055_generaloption_main_site_url'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='RadiusOption',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('radius_general_policy', models.CharField(choices=[('MACHINE', "On the IP range's VLAN of the machine"), ('DEFINED', "Preset in 'VLAN for machines accepted by RADIUS'")], default='DEFINED', max_length=32)),
+ ],
+ options={
+ 'verbose_name': 'radius policies',
+ },
+ bases=(re2o.mixins.AclMixin, models.Model),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='banned_vlan',
+ field=models.ForeignKey(blank=True, help_text='Vlan for banned if not rejected.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='banned_vlan', to='machines.Vlan', verbose_name='Banned Vlan'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='non_member_vlan',
+ field=models.ForeignKey(blank=True, help_text='Vlan for non members if not rejected.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='non_member_vlan', to='machines.Vlan', verbose_name='Non member Vlan'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='unknown_machine_vlan',
+ field=models.ForeignKey(blank=True, help_text='Vlan for unknown machines if not rejected.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='unknown_machine_vlan', to='machines.Vlan', verbose_name='Unknown machine Vlan'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='unknown_port_vlan',
+ field=models.ForeignKey(blank=True, help_text='Vlan for unknown ports if not rejected.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='unknown_port_vlan', to='machines.Vlan', verbose_name='Unknown port Vlan'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='unknown_room_vlan',
+ field=models.ForeignKey(blank=True, help_text='Vlan for unknown room if not rejected.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='unknown_room_vlan', to='machines.Vlan', verbose_name='Unknown room Vlan'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='banned',
+ field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for banned users.'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='non_member',
+ field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy non member users.'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='unknown_machine',
+ field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for unknown machines'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='unknown_port',
+ field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for unknown machines'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='unknown_room',
+ field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for machine connecting from unregistered room (relevant on ports with STRICT radius mode)'),
+ ),
+ migrations.AddField(
+ model_name='radiusoption',
+ name='vlan_decision_ok',
+ field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vlan_ok_option', to='machines.Vlan'),
+ ),
+
+ migrations.RunPython(create_radius_policy),
+ migrations.RemoveField(
+ model_name='optionaltopologie',
+ name='radius_general_policy',
+ ),
+ migrations.RemoveField(
+ model_name='optionaltopologie',
+ name='vlan_decision_nok',
+ ),
+ migrations.RemoveField(
+ model_name='optionaltopologie',
+ name='vlan_decision_ok',
+ ),
+ ]
diff --git a/preferences/migrations/0057_auto_20181204_0757.py b/preferences/migrations/0057_auto_20181204_0757.py
new file mode 100644
index 00000000..ba4e1a6f
--- /dev/null
+++ b/preferences/migrations/0057_auto_20181204_0757.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.7 on 2018-12-04 13:57
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('preferences', '0056_radiusoption'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='radiusoption',
+ name='unknown_port',
+ field=models.CharField(choices=[('REJECT', 'Reject the machine'), ('SET_VLAN', 'Place the machine on the VLAN')], default='REJECT', max_length=32, verbose_name='Policy for unknown port'),
+ ),
+ ]
diff --git a/preferences/models.py b/preferences/models.py
index 43ff7580..4644aa1c 100644
--- a/preferences/models.py
+++ b/preferences/models.py
@@ -199,25 +199,6 @@ class OptionalTopologie(AclMixin, PreferencesModel):
('tftp', 'tftp'),
)
- radius_general_policy = models.CharField(
- max_length=32,
- choices=CHOICE_RADIUS,
- default='DEFINED'
- )
- vlan_decision_ok = models.OneToOneField(
- 'machines.Vlan',
- on_delete=models.PROTECT,
- related_name='decision_ok',
- blank=True,
- null=True
- )
- vlan_decision_nok = models.OneToOneField(
- 'machines.Vlan',
- on_delete=models.PROTECT,
- related_name='decision_nok',
- blank=True,
- null=True
- )
switchs_web_management = models.BooleanField(
default=False,
help_text="Web management, activé si provision automatique"
@@ -309,7 +290,6 @@ class OptionalTopologie(AclMixin, PreferencesModel):
"""Return true if all settings are ok : switchs on automatic provision,
ip_type"""
return bool(self.provisioned_switchs and self.switchs_ip_type and SwitchManagementCred.objects.filter(default_switch=True).exists() and self.switchs_management_interface_ip and bool(self.switchs_provision != 'sftp' or self.switchs_management_sftp_creds))
-
class Meta:
permissions = (
("view_optionaltopologie", _("Can view the topology options")),
@@ -588,3 +568,122 @@ class MailMessageOption(AclMixin, models.Model):
)
verbose_name = _("email message options")
+
+class RadiusOption(AclMixin, PreferencesModel):
+ class Meta:
+ verbose_name = _("radius policies")
+
+ MACHINE = 'MACHINE'
+ DEFINED = 'DEFINED'
+ CHOICE_RADIUS = (
+ (MACHINE, _("On the IP range's VLAN of the machine")),
+ (DEFINED, _("Preset in 'VLAN for machines accepted by RADIUS'")),
+ )
+ REJECT = 'REJECT'
+ SET_VLAN = 'SET_VLAN'
+ CHOICE_POLICY = (
+ (REJECT, _('Reject the machine')),
+ (SET_VLAN, _('Place the machine on the VLAN'))
+ )
+ radius_general_policy = models.CharField(
+ max_length=32,
+ choices=CHOICE_RADIUS,
+ default='DEFINED'
+ )
+ unknown_machine = models.CharField(
+ max_length=32,
+ choices=CHOICE_POLICY,
+ default=REJECT,
+ verbose_name=_("Policy for unknown machines"),
+ )
+ unknown_machine_vlan = models.ForeignKey(
+ 'machines.Vlan',
+ on_delete=models.PROTECT,
+ related_name='unknown_machine_vlan',
+ blank=True,
+ null=True,
+ verbose_name=_('Unknown machine Vlan'),
+ help_text=_(
+ 'Vlan for unknown machines if not rejected.'
+ )
+ )
+ unknown_port = models.CharField(
+ max_length=32,
+ choices=CHOICE_POLICY,
+ default=REJECT,
+ verbose_name=_("Policy for unknown port"),
+ )
+ unknown_port_vlan = models.ForeignKey(
+ 'machines.Vlan',
+ on_delete=models.PROTECT,
+ related_name='unknown_port_vlan',
+ blank=True,
+ null=True,
+ verbose_name=_('Unknown port Vlan'),
+ help_text=_(
+ 'Vlan for unknown ports if not rejected.'
+ )
+ )
+ unknown_room = models.CharField(
+ max_length=32,
+ choices=CHOICE_POLICY,
+ default=REJECT,
+ verbose_name=_(
+ "Policy for machine connecting from "
+ "unregistered room (relevant on ports with STRICT "
+ "radius mode)"
+ ),
+ )
+ unknown_room_vlan = models.ForeignKey(
+ 'machines.Vlan',
+ related_name='unknown_room_vlan',
+ on_delete=models.PROTECT,
+ blank=True,
+ null=True,
+ verbose_name=_('Unknown room Vlan'),
+ help_text=_(
+ 'Vlan for unknown room if not rejected.'
+ )
+ )
+ non_member = models.CharField(
+ max_length=32,
+ choices=CHOICE_POLICY,
+ default=REJECT,
+ verbose_name=_("Policy non member users."),
+ )
+ non_member_vlan = models.ForeignKey(
+ 'machines.Vlan',
+ related_name='non_member_vlan',
+ on_delete=models.PROTECT,
+ blank=True,
+ null=True,
+ verbose_name=_('Non member Vlan'),
+ help_text=_(
+ 'Vlan for non members if not rejected.'
+ )
+ )
+ banned = models.CharField(
+ max_length=32,
+ choices=CHOICE_POLICY,
+ default=REJECT,
+ verbose_name=_("Policy for banned users."),
+ )
+ banned_vlan = models.ForeignKey(
+ 'machines.Vlan',
+ related_name='banned_vlan',
+ on_delete=models.PROTECT,
+ blank=True,
+ null=True,
+ verbose_name=_('Banned Vlan'),
+ help_text=_(
+ 'Vlan for banned if not rejected.'
+ )
+ )
+ vlan_decision_ok = models.OneToOneField(
+ 'machines.Vlan',
+ on_delete=models.PROTECT,
+ related_name='vlan_ok_option',
+ blank=True,
+ null=True
+ )
+
diff --git a/preferences/templates/preferences/aff_radiusoptions.html b/preferences/templates/preferences/aff_radiusoptions.html
new file mode 100644
index 00000000..17e2a869
--- /dev/null
+++ b/preferences/templates/preferences/aff_radiusoptions.html
@@ -0,0 +1,96 @@
+{% comment %}
+Re2o est un logiciel d'administration développé initiallement au rezometz. Il
+se veut agnostique au réseau considéré, de manière à être installable en
+quelques clics.
+
+Copyright © 2018 Hugo Levy-Falk
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+{% endcomment %}
+{% load i18n %}
+{% load acl %}
+{% load logs_extra %}
+
+
+
+ {% trans "General policy for VLAN setting" %} |
+ {{ radiusoptions.radius_general_policy }} |
+ {% trans "This setting defines the VLAN policy after acceptance by RADIUS: either on the IP range's VLAN of the machine, or a VLAN preset in 'VLAN for machines accepted by RADIUS'" %} |
+
+
+ {% trans "VLAN for machines accepted by RADIUS" %} |
+ Vlan {{ radiusoptions.vlan_decision_ok }} |
+
+
+
+
+
+
+ {% trans "Situation" %} |
+ {% trans "Behavior" %} |
+
+
+
+ {% trans "Unknown machine" %} |
+
+ {% if radiusoptions.unknown_machine == 'REJECT' %}
+ {% trans "Reject" %}
+ {% else %}
+ Vlan {{ radiusoptions.unknown_machine_vlan }}
+ {% endif %}
+ |
+
+
+ {% trans "Unknown port" %} |
+
+ {% if radiusoptions.unknown_port == 'REJECT' %}
+ {% trans "Reject" %}
+ {% else %}
+ Vlan {{ radiusoptions.unknown_port_vlan }}
+ {% endif %}
+ |
+
+
+ {% trans "Unknown room" %} |
+
+ {% if radiusoptions.unknown_room == 'REJECT' %}
+ {% trans "Reject" %}
+ {% else %}
+ Vlan {{ radiusoptions.unknown_room_vlan }}
+ {% endif %}
+ |
+
+
+ {% trans "Non member" %} |
+
+ {% if radiusoptions.non_member == 'REJECT' %}
+ {% trans "Reject" %}
+ {% else %}
+ Vlan {{ radiusoptions.non_member_vlan }}
+ {% endif %}
+ |
+
+
+ {% trans "Banned user" %} |
+
+ {% if radiusoptions.unknown_port == 'REJECT' %}
+ {% trans "Reject" %}
+ {% else %}
+ Vlan {{ radiusoptions.banned_vlan }}
+ {% endif %}
+ |
+
+
+
diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html
index 3fde911d..0e34d6e9 100644
--- a/preferences/templates/preferences/display_preferences.html
+++ b/preferences/templates/preferences/display_preferences.html
@@ -32,312 +32,323 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block content %}
-
-
-
-
+
+ {% trans "Website name" %} |
+ {{ generaloptions.site_name }} |
+ {% trans "Email address for automatic emailing" %} |
+ {{ generaloptions.email_from }} |
+
+
+ {% trans "Number of results displayed when searching" %} |
+ {{ generaloptions.search_display_page }} |
+ {% trans "Number of items per page (standard size)" %} |
+ {{ generaloptions.pagination_number }} |
+
+
+ {% trans "Number of items per page (large size)" %} |
+ {{ generaloptions.pagination_large_number }} |
+ {% trans "Time before expiration of the reset password link (in hours)" %} |
+ {{ generaloptions.req_expire_hrs }} |
+
+
+ {% trans "General message displayed on the website" %} |
+ {{ generaloptions.general_message }} |
+ {% trans "Main site url" %} |
+ {{ generaloptions.main_site_url }} |
+
+
+ {% trans "Summary of the General Terms of Use" %} |
+ {{ generaloptions.GTU_sum_up }} |
+ {% trans "General Terms of Use" %} |
+ {{ generaloptions.GTU }}
+ |
+
+
+
+ {% trans "Local email accounts enabled" %} |
+ {{ useroptions.local_email_accounts_enabled|tick }} |
+ {% trans "Local email domain" %} |
+ {{ useroptions.local_email_domain }} |
+
+
+ {% trans "Maximum number of email aliases allowed" %} |
+ {{ useroptions.max_email_address }} |
+
+
+
+
-
-
-
+
+
+
-
-
-
- {% trans "Edit" %}
-
-
+
+
+
+ {% trans "Edit" %}
+
+
-
-
- {% trans "Creation of members by everyone" %} |
- {{ useroptions.all_can_create_adherent|tick }} |
- {% trans "Creation of clubs by everyone" %} |
- {{ useroptions.all_can_create_club|tick }} |
-
-
- {% trans "Self registration" %} |
- {{ useroptions.self_adhesion|tick }} |
- {% trans "Delete not yet active users after" %} |
- {{ useroptions.delete_notyetactive }} days |
-
+
+
+ {% trans "Creation of members by everyone" %} |
+ {{ useroptions.all_can_create_adherent|tick }} |
+ {% trans "Creation of clubs by everyone" %} |
+ {{ useroptions.all_can_create_club|tick }} |
+
+
+ {% trans "Self registration" %} |
+ {{ useroptions.self_adhesion|tick }} |
+ {% trans "Delete not yet active users after" %} |
+ {{ useroptions.delete_notyetactive }} days |
+
{% trans "Users general permissions" %}
-
- {% trans "Default shell for users" %} |
- {{ useroptions.shell_default }} |
- {% trans "Users can edit their shell" %} |
- {{ useroptions.self_change_shell|tick }} |
-
-
- {% trans "Users can edit their room" %} |
- {{ useroptions.self_change_room|tick }} |
- {% trans "Telephone number required" %} |
- {{ useroptions.is_tel_mandatory|tick }} |
-
-
- {% trans "GPG fingerprint field" %} |
- {{ useroptions.gpg_fingerprint|tick }} |
-
-
-
+
+ {% trans "Default shell for users" %} |
+ {{ useroptions.shell_default }} |
+ {% trans "Users can edit their shell" %} |
+ {{ useroptions.self_change_shell|tick }} |
+
+
+ {% trans "Users can edit their room" %} |
+ {{ useroptions.self_change_room|tick }} |
+ {% trans "Telephone number required" %} |
+ {{ useroptions.is_tel_mandatory|tick }} |
+
+
+ {% trans "GPG fingerprint field" %} |
+ {{ useroptions.gpg_fingerprint|tick }} |
+
+
-
-
-
+
+
-
-
- {% trans "Edit" %}
-
-
-
-
- {% trans "Password per machine" %} |
- {{ machineoptions.password_machine|tick }} |
- {% trans "Maximum number of interfaces allowed for a standard user" %} |
- {{ machineoptions.max_lambdauser_interfaces }} |
-
-
- {% trans "Maximum number of DNS aliases allowed for a standard user" %} |
- {{ machineoptions.max_lambdauser_aliases }} |
- {% trans "IPv6 support" %} |
- {{ machineoptions.ipv6_mode }} |
-
-
- {% trans "Creation of machines" %} |
- {{ machineoptions.create_machine|tick }} |
-
-
-
-
+
-
-
-
-
-
+
{% trans "Edit" %}
-
-
- {% trans "General policy for VLAN setting" %} |
- {{ topologieoptions.radius_general_policy }} |
- {% trans "This setting defines the VLAN policy after acceptance by RADIUS: either on the IP range's VLAN of the machine, or a VLAN preset in 'VLAN for machines accepted by RADIUS'" %} |
- |
-
-
- {% trans "VLAN for machines accepted by RADIUS" %} |
- {{ topologieoptions.vlan_decision_ok }} |
- {% trans "VLAN for machines rejected by RADIUS" %} |
- {{ topologieoptions.vlan_decision_nok }} |
-
-
- Placement sur ce vlan par default en cas de rejet |
- {{ topologieoptions.vlan_decision_nok }} |
-
-
-
-
Clef radius
- {% can_create RadiusKey%}
-
Ajouter une clef radius
- {% acl_end %}
- {% include "preferences/aff_radiuskey.html" with radiuskey_list=radiuskey_list %}
-
-
-
-
-
-
-
-
-
-
- {% trans "Edit" %}
-
-
-
-
- Web management, activé si provision automatique |
- {{ topologieoptions.switchs_web_management }} |
- Rest management, activé si provision auto |
- {{ topologieoptions.switchs_rest_management }} |
-
-
+
+ {% trans "Password per machine" %} |
+ {{ machineoptions.password_machine|tick }} |
+ {% trans "Maximum number of interfaces allowed for a standard user" %} |
+ {{ machineoptions.max_lambdauser_interfaces }} |
+
+
+ {% trans "Maximum number of DNS aliases allowed for a standard user" %} |
+ {{ machineoptions.max_lambdauser_aliases }} |
+ {% trans "IPv6 support" %} |
+ {{ machineoptions.ipv6_mode }} |
+
+
+ {% trans "Creation of machines" %} |
+ {{ machineoptions.create_machine|tick }} |
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "Edit" %}
+
+
+
+
+ {% trans "General policy for VLAN setting" %} |
+ {{ topologieoptions.radius_general_policy }} |
+ {% trans "This setting defines the VLAN policy after acceptance by RADIUS: either on the IP range's VLAN of the machine, or a VLAN preset in 'VLAN for machines accepted by RADIUS'" %} |
+ |
+
+
+ {% trans "VLAN for machines accepted by RADIUS" %} |
+ {{ topologieoptions.vlan_decision_ok }} |
+ {% trans "VLAN for machines rejected by RADIUS" %} |
+ {{ topologieoptions.vlan_decision_nok }} |
+
+
+ {% trans "VLAN for non members machines" %} |
+ {{ topologieoptions.vlan_non_member }} |
+
+
+
+
Clef radius
+ {% can_create RadiusKey%}
+
Ajouter une clef radius
+ {% acl_end %}
+ {% include "preferences/aff_radiuskey.html" with radiuskey_list=radiuskey_list %}
+
+
+
+
+
+
+
+
+
+
+ {% trans "Edit" %}
+
+
+
+
+
+ Web management, activé si provision automatique |
+ {{ topologieoptions.switchs_web_management }} |
+ Rest management, activé si provision auto |
+ {{ topologieoptions.switchs_rest_management }} |
+
+
-
{% if topologieoptions.provision_switchs_enabled %}Provision de la config des switchs{% else %}Provision de la config des switchs{% endif%}
-
-
- Switchs configurés automatiquement |
- {{ topologieoptions.provisioned_switchs|join:", " }} {% if topologieoptions.provisioned_switchs %} OK{% else %}Manquant{% endif %} |
-
-
- Plage d'ip de management des switchs |
- {{ topologieoptions.switchs_ip_type }} {% if topologieoptions.switchs_ip_type %} OK{% else %}Manquant{% endif %} |
-
-
- Serveur des config des switchs |
- {{ topologieoptions.switchs_management_interface }} {% if topologieoptions.switchs_management_interface %} - {{ topologieoptions.switchs_management_interface_ip }} OK{% else %}Manquant{% endif %} |
-
-
- Mode de provision des switchs |
- {{ topologieoptions.switchs_provision }} |
-
-
- Mode TFTP |
- OK |
-
-
- Mode SFTP |
- {% if topologieoptions.switchs_management_sftp_creds %} OK{% else %}Creds manquants{% endif %} |
-
-
+
{% if topologieoptions.provision_switchs_enabled %}Provision de la config des switchs{% else %}Provision de la config des switchs{% endif%}
+
+
+ Switchs configurés automatiquement |
+ {{ topologieoptions.provisioned_switchs|join:", " }} {% if topologieoptions.provisioned_switchs %} OK{% else %}Manquant{% endif %} |
+
+
+ Plage d'ip de management des switchs |
+ {{ topologieoptions.switchs_ip_type }} {% if topologieoptions.switchs_ip_type %} OK{% else %}Manquant{% endif %} |
+
+
+ Serveur des config des switchs |
+ {{ topologieoptions.switchs_management_interface }} {% if topologieoptions.switchs_management_interface %} - {{ topologieoptions.switchs_management_interface_ip }} OK{% else %}Manquant{% endif %} |
+
+
+ Mode de provision des switchs |
+ {{ topologieoptions.switchs_provision }} |
+
+
+ Mode TFTP |
+ OK |
+
+
+ Mode SFTP |
+ {% if topologieoptions.switchs_management_sftp_creds %} OK{% else %}Creds manquants{% endif %} |
+
+
-
Creds de management des switchs
- {% can_create SwitchManagementCred%}
-
Ajouter un id/mdp de management switch
- {% acl_end %}
-
-
- {% if switchmanagementcred_list %}
OK{% else %}Manquant{% endif %}
- {% include "preferences/aff_switchmanagementcred.html" with switchmanagementcred_list=switchmanagementcred_list %}
-
-
+
Creds de management des switchs
+ {% can_create SwitchManagementCred%}
+
Ajouter un id/mdp de management switch
+ {% acl_end %}
+
+
+ {% if switchmanagementcred_list %}
OK{% else %}Manquant{% endif %}
+ {% include "preferences/aff_switchmanagementcred.html" with switchmanagementcred_list=switchmanagementcred_list %}
+
+
+
-
+
-
{% trans "Edit" %}
-
-
- {% trans "Name" %} |
- {{ assooptions.name }} |
- {% trans "SIRET number" %} |
- {{ assooptions.siret }} |
-
-
- {% trans "Address" %} |
- {{ assooptions.adresse1 }}
- {{ assooptions.adresse2 }}
- |
- {% trans "Contact email address" %} |
- {{ assooptions.contact }} |
-
-
- {% trans "Telephone number" %} |
- {{ assooptions.telephone }} |
- {% trans "Usual name" %} |
- {{ assooptions.pseudo }} |
-
-
- {% trans "User object of the organisation" %} |
- {{ assooptions.utilisateur_asso }} |
- {% trans "Description of the organisation" %} |
- {{ assooptions.description|safe }} |
-
-
+
+
+ {% trans "Name" %} |
+ {{ assooptions.name }} |
+ {% trans "SIRET number" %} |
+ {{ assooptions.siret }} |
+
+
+ {% trans "Address" %} |
+ {{ assooptions.adresse1 }}
+ {{ assooptions.adresse2 }}
+ |
+ {% trans "Contact email address" %} |
+ {{ assooptions.contact }} |
+
+
+ {% trans "Telephone number" %} |
+ {{ assooptions.telephone }} |
+ {% trans "Usual name" %} |
+ {{ assooptions.pseudo }} |
+
+
+ {% trans "User object of the organisation" %} |
+ {{ assooptions.utilisateur_asso }} |
+ {% trans "Description of the organisation" %} |
+ {{ assooptions.description|safe }} |
+
+
-
-
-
+
+
+
@@ -346,61 +357,61 @@ with this program; if not, write to the Free Software Foundation, Inc.,
-
-
- {% trans "Welcome email (in French)" %} |
- {{ mailmessageoptions.welcome_mail_fr|safe }} |
-
-
- {% trans "Welcome email (in English)" %} |
- {{ mailmessageoptions.welcome_mail_en|safe }} |
-
-
-
-
+
+
+ {% trans "Welcome email (in French)" %} |
+ {{ mailmessageoptions.welcome_mail_fr|safe }} |
+
+
+ {% trans "Welcome email (in English)" %} |
+ {{ mailmessageoptions.welcome_mail_en|safe }} |
+
+
+
+
-
+
-
+
{% can_create preferences.Reminder%}
-
+
Ajouter un rappel
{% acl_end %}
{% include "preferences/aff_reminder.html" with reminder_list=reminder_list %}
-
+
-
+
{% can_create preferences.Service%}
-
+
{% trans " Add a service" %}
{% acl_end %}
{% include "preferences/aff_service.html" with service_list=service_list %}
-
-
-
-
+
+
+
+
+
-
+
@@ -423,20 +434,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% trans "Edit" %}
-
-
- {% trans "Twitter account URL" %} |
- {{ homeoptions.twitter_url }} |
- {% trans "Twitter account name" %} |
- {{ homeoptions.twitter_account_name }} |
-
-
- {% trans "Facebook account URL" %} |
- {{ homeoptions.facebook_url }} |
-
-
-
+
+
+ {% trans "Twitter account URL" %} |
+ {{ homeoptions.twitter_url }} |
+ {% trans "Twitter account name" %} |
+ {{ homeoptions.twitter_account_name }} |
+
+
+ {% trans "Facebook account URL" %} |
+ {{ homeoptions.facebook_url }} |
+
+
+
{% endblock %}
diff --git a/preferences/templates/preferences/edit_preferences.html b/preferences/templates/preferences/edit_preferences.html
index a1540f33..c3dd4652 100644
--- a/preferences/templates/preferences/edit_preferences.html
+++ b/preferences/templates/preferences/edit_preferences.html
@@ -37,6 +37,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
diff --git a/preferences/urls.py b/preferences/urls.py
index 63ca6a39..30163868 100644
--- a/preferences/urls.py
+++ b/preferences/urls.py
@@ -66,6 +66,11 @@ urlpatterns = [
views.edit_options,
name='edit-options'
),
+ url(
+ r'^edit_options/(?PRadiusOption)$',
+ views.edit_options,
+ name='edit-options'
+ ),
url(r'^add_service/$', views.add_service, name='add-service'),
url(
r'^edit_service/(?P[0-9]+)$',
diff --git a/preferences/views.py b/preferences/views.py
index ee81ae89..586be60f 100644
--- a/preferences/views.py
+++ b/preferences/views.py
@@ -62,7 +62,8 @@ from .models import (
HomeOption,
Reminder,
RadiusKey,
- SwitchManagementCred
+ SwitchManagementCred,
+ RadiusOption,
)
from . import models
from . import forms
@@ -86,6 +87,7 @@ def display_options(request):
reminder_list = Reminder.objects.all()
radiuskey_list = RadiusKey.objects.all()
switchmanagementcred_list = SwitchManagementCred.objects.all()
+ radiusoptions, _ = RadiusOption.objects.get_or_create()
return form({
'useroptions': useroptions,
'machineoptions': machineoptions,
@@ -98,7 +100,8 @@ def display_options(request):
'mailcontact_list': mailcontact_list,
'reminder_list': reminder_list,
'radiuskey_list' : radiuskey_list,
- 'switchmanagementcred_list': switchmanagementcred_list,
+ 'switchmanagementcred_list': switchmanagementcred_list,
+ 'radiusoptions' : radiusoptions,
}, 'preferences/display_preferences.html', request)
@@ -134,7 +137,9 @@ def edit_options(request, section):
messages.success(request, _("The preferences were edited."))
return redirect(reverse('preferences:display-options'))
return form(
- {'options': options},
+ {
+ 'options': options,
+ },
'preferences/edit_preferences.html',
request
)
diff --git a/users/forms.py b/users/forms.py
index b96e3ad3..70d8798b 100644
--- a/users/forms.py
+++ b/users/forms.py
@@ -384,8 +384,8 @@ class AdherentCreationForm(AdherentForm):
# Checkbox for GTU
gtu_check = forms.BooleanField(required=True)
- gtu_check.label = mark_safe("{} {}{}".format(
- _("I commit to accept the"), GeneralOption.get_cached_value('GTU'), _("General Terms of Use"), _(".")))
+ #gtu_check.label = mark_safe("{} {}{}".format(
+ # _("I commit to accept the"), GeneralOption.get_cached_value('GTU'), _("General Terms of Use"), _(".")))
def __init__(self, *args, **kwargs):
super(AdherentCreationForm, self).__init__(*args, **kwargs)
- Réseaux sociaux + Réseaux sociaux