8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-23 23:43:47 +00:00
re2o/preferences/models.py

450 lines
13 KiB
Python
Raw Normal View History

# -*- mode: python; coding: utf-8 -*-
# Re2o 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 © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# 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.
"""
Reglages généraux, machines, utilisateurs, mail, general pour l'application.
"""
from __future__ import unicode_literals
from django.utils.functional import cached_property
from django.db import models
2018-04-14 18:55:24 +00:00
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.cache import cache
2018-04-14 18:55:24 +00:00
import cotisations.models
import machines.models
2018-03-28 15:39:23 +00:00
from re2o.mixins import AclMixin
2018-04-14 18:55:24 +00:00
from .aes_field import AESEncryptedField
2018-04-13 23:42:22 +00:00
2018-01-31 19:43:36 +00:00
class PreferencesModel(models.Model):
2018-04-14 18:55:24 +00:00
""" Base object for the Preferences objects
Defines methods to handle the cache of the settings (they should
not change a lot) """
2018-01-31 19:43:36 +00:00
@classmethod
def set_in_cache(cls):
2018-04-14 18:55:24 +00:00
""" Save the preferences in a server-side cache """
2018-01-31 19:43:36 +00:00
instance, _created = cls.objects.get_or_create()
cache.set(cls().__class__.__name__.lower(), instance, None)
return instance
@classmethod
def get_cached_value(cls, key):
2018-04-14 18:55:24 +00:00
""" Get the preferences from the server-side cache """
2018-01-31 19:43:36 +00:00
instance = cache.get(cls().__class__.__name__.lower())
2018-04-13 23:42:22 +00:00
if instance is None:
instance = cls.set_in_cache()
2018-01-31 19:43:36 +00:00
return getattr(instance, key)
class Meta:
abstract = True
2018-03-28 15:39:23 +00:00
class OptionalUser(AclMixin, PreferencesModel):
"""Options pour l'user : obligation ou nom du telephone,
activation ou non du solde, autorisation du negatif, fingerprint etc"""
PRETTY_NAME = "Options utilisateur"
is_tel_mandatory = models.BooleanField(
default=True,
help_text="Obligation de renseigner le téléphone"
)
user_solde = models.BooleanField(
default=False,
help_text="Solde pour les users"
)
solde_negatif = models.DecimalField(
max_digits=5,
decimal_places=2,
default=0,
help_text="Maximum de négatif autorisé"
)
2018-01-12 00:07:25 +00:00
max_solde = models.DecimalField(
max_digits=5,
decimal_places=2,
default=50,
help_text="Valeur maximum du solde"
)
min_online_payment = models.DecimalField(
max_digits=5,
decimal_places=2,
default=10,
help_text="Montant minimum pour le rechargement online"
)
gpg_fingerprint = models.BooleanField(
default=True,
help_text="Gpg fingerprint activée")
all_can_create_club = models.BooleanField(
2017-11-21 04:47:05 +00:00
default=False,
help_text="Les users peuvent créer un club"
)
all_can_create_adherent = models.BooleanField(
default=False,
help_text="Les users peuvent créer d'autres adhérents",
2017-11-21 04:47:05 +00:00
)
self_adhesion = models.BooleanField(
default=False,
help_text="Un nouvel utilisateur peut se créer son compte sur re2o"
)
2018-03-24 20:19:52 +00:00
shell_default = models.OneToOneField(
'users.ListShell',
on_delete=models.PROTECT,
blank=True,
null=True,
help_text="Shell par default"
2018-03-24 20:19:52 +00:00
)
class Meta:
permissions = (
("view_optionaluser", "Peut voir les options de l'user"),
)
2017-06-26 17:23:01 +00:00
def clean(self):
"""Creation du mode de paiement par solde"""
2017-06-26 17:23:01 +00:00
if self.user_solde:
p = cotisations.models.Paiement.objects.filter(moyen="Solde")
if not len(p):
c = cotisations.models.Paiement(moyen="Solde")
c.save()
2017-06-26 17:23:01 +00:00
@receiver(post_save, sender=OptionalUser)
2018-04-15 01:00:05 +00:00
def optionaluser_post_save(**kwargs):
"""Ecriture dans le cache"""
user_pref = kwargs['instance']
user_pref.set_in_cache()
2018-03-28 15:39:23 +00:00
class OptionalMachine(AclMixin, PreferencesModel):
"""Options pour les machines : maximum de machines ou d'alias par user
sans droit, activation de l'ipv6"""
PRETTY_NAME = "Options machines"
SLAAC = 'SLAAC'
DHCPV6 = 'DHCPV6'
DISABLED = 'DISABLED'
CHOICE_IPV6 = (
(SLAAC, 'Autoconfiguration par RA'),
(DHCPV6, 'Attribution des ip par dhcpv6'),
(DISABLED, 'Désactivé'),
)
password_machine = models.BooleanField(
default=False,
help_text="Un mot de passe par machine activé")
max_lambdauser_interfaces = models.IntegerField(
default=10,
help_text="Maximum d'interface pour un user sans droits")
max_lambdauser_aliases = models.IntegerField(
default=10,
help_text="Maximum de cname pour un user sans droits")
ipv6_mode = models.CharField(
max_length=32,
choices=CHOICE_IPV6,
default='DISABLED',
help_text="Mode ipv6"
)
create_machine = models.BooleanField(
default=True,
help_text="Permet à l'user de créer une machine"
)
@cached_property
def ipv6(self):
2018-04-14 18:55:24 +00:00
""" Check if the IPv6 option is activated """
2018-04-13 23:42:22 +00:00
return not self.get_cached_value('ipv6_mode') == 'DISABLED'
class Meta:
permissions = (
("view_optionalmachine", "Peut voir les options de machine"),
)
@receiver(post_save, sender=OptionalMachine)
2018-04-15 01:00:05 +00:00
def optionalmachine_post_save(**kwargs):
"""Synchronisation ipv6 et ecriture dans le cache"""
machine_pref = kwargs['instance']
machine_pref.set_in_cache()
if machine_pref.ipv6_mode != "DISABLED":
for interface in machines.models.Interface.objects.all():
interface.sync_ipv6()
2018-03-28 15:39:23 +00:00
class OptionalTopologie(AclMixin, PreferencesModel):
"""Reglages pour la topologie : mode d'accès radius, vlan où placer
les machines en accept ou reject"""
PRETTY_NAME = "Options topologie"
MACHINE = 'MACHINE'
DEFINED = 'DEFINED'
CHOICE_RADIUS = (
(MACHINE, 'Sur le vlan de la plage ip machine'),
(DEFINED, 'Prédéfini dans "Vlan où placer les machines\
après acceptation RADIUS"'),
)
radius_general_policy = models.CharField(
max_length=32,
choices=CHOICE_RADIUS,
default='DEFINED',
help_text="Politique par defaut de placement de vlan avec radius"
)
vlan_decision_ok = models.OneToOneField(
'machines.Vlan',
on_delete=models.PROTECT,
related_name='decision_ok',
blank=True,
null=True,
help_text="Placement sur ce vlan par default en cas d'accès OK"
)
vlan_decision_nok = models.OneToOneField(
'machines.Vlan',
on_delete=models.PROTECT,
related_name='decision_nok',
blank=True,
null=True,
help_text="Placement par defaut sur ce vlan en cas de rejet"
)
2017-09-10 16:16:59 +00:00
class Meta:
permissions = (
("view_optionaltopologie", "Peut voir les options de topologie"),
)
@receiver(post_save, sender=OptionalTopologie)
2018-04-15 01:00:05 +00:00
def optionaltopologie_post_save(**kwargs):
"""Ecriture dans le cache"""
topologie_pref = kwargs['instance']
topologie_pref.set_in_cache()
2018-03-28 15:39:23 +00:00
class GeneralOption(AclMixin, PreferencesModel):
"""Options générales : nombre de resultats par page, nom du site,
temps les liens sont valides"""
PRETTY_NAME = "Options générales"
general_message = models.TextField(
default="",
blank=True,
help_text="Message général affiché sur le site (maintenance, etc)"
)
search_display_page = models.IntegerField(
default=15,
help_text="Nombre de résultats affichés dans une recherche"
)
pagination_number = models.IntegerField(
default=25,
help_text="Nombre d'item par page paginée"
)
pagination_large_number = models.IntegerField(
default=8,
help_text="Nombre d'item par page paginée, items larges"
)
req_expire_hrs = models.IntegerField(
default=48,
help_text="Delais d'expiration des token changement de mdp, en heure"
)
site_name = models.CharField(
max_length=32,
default="Re2o",
help_text="Nom du site web, par defaut re2o"
)
email_from = models.EmailField(
default="www-data@example.com",
help_text="From des mails envoyés par re2o"
)
2018-01-14 22:47:44 +00:00
GTU_sum_up = models.TextField(
default="",
blank=True,
help_text="Résumé des CGU à l'inscription"
2018-01-14 22:47:44 +00:00
)
GTU = models.FileField(
2018-04-13 23:42:22 +00:00
upload_to='',
2018-01-14 22:47:44 +00:00
default="",
null=True,
blank=True,
help_text="CGU et documents réglementaires à l'inscription"
2018-01-14 22:47:44 +00:00
)
class Meta:
permissions = (
("view_generaloption", "Peut voir les options générales"),
)
@receiver(post_save, sender=GeneralOption)
2018-04-15 01:00:05 +00:00
def generaloption_post_save(**kwargs):
"""Ecriture dans le cache"""
general_pref = kwargs['instance']
general_pref.set_in_cache()
2018-03-28 15:39:23 +00:00
class Service(AclMixin, models.Model):
"""Liste des services affichés sur la page d'accueil : url, description,
image et nom"""
name = models.CharField(max_length=32)
url = models.URLField()
description = models.TextField()
image = models.ImageField(upload_to='logo', blank=True)
class Meta:
permissions = (
("view_service", "Peut voir les options de service"),
)
def __str__(self):
return str(self.name)
2018-03-28 15:39:23 +00:00
class AssoOption(AclMixin, PreferencesModel):
"""Options générales de l'asso : siret, addresse, nom, etc"""
PRETTY_NAME = "Options de l'association"
name = models.CharField(
default="Association réseau école machin",
max_length=256,
help_text="Nom complet de l'asso"
)
siret = models.CharField(
default="00000000000000",
max_length=32,
help_text="Numero SIRET"
)
adresse1 = models.CharField(
default="1 Rue de exemple",
max_length=128,
help_text="Adresse"
)
adresse2 = models.CharField(
default="94230 Cachan",
max_length=128
)
contact = models.EmailField(
default="contact@example.org",
help_text="Mail de contact"
)
telephone = models.CharField(
max_length=15,
default="0000000000",
help_text="Téléphone de contact"
)
pseudo = models.CharField(
default="Asso",
max_length=32,
help_text="Pseudo de l'asso"
)
utilisateur_asso = models.OneToOneField(
'users.User',
on_delete=models.PROTECT,
blank=True,
null=True,
help_text="Utilisateur dans la db correspondant à l'asso"
)
PAYMENT = (
('NONE', 'NONE'),
('COMNPAY', 'COMNPAY'),
)
payment = models.CharField(
max_length=255,
choices=PAYMENT,
default='NONE',
help_text="Mode de paiement en ligne"
)
payment_id = models.CharField(
max_length=255,
default='',
blank=True,
help_text="Id de paiement en ligne"
)
payment_pass = AESEncryptedField(
max_length=255,
2018-01-29 16:46:46 +00:00
null=True,
blank=True,
help_text="Clef de paiement en ligne"
)
2018-03-18 01:14:45 +00:00
description = models.TextField(
null=True,
blank=True,
help_text="Description de l'asso"
2018-03-18 01:14:45 +00:00
)
class Meta:
permissions = (
("view_assooption", "Peut voir les options de l'asso"),
)
@receiver(post_save, sender=AssoOption)
2018-04-15 01:00:05 +00:00
def assooption_post_save(**kwargs):
"""Ecriture dans le cache"""
asso_pref = kwargs['instance']
asso_pref.set_in_cache()
2018-04-16 16:22:51 +00:00
class HomeOption(AclMixin, PreferencesModel):
"""Settings of the home page (facebook/twitter etc)"""
2018-04-16 03:28:27 +00:00
PRETTY_NAME = "Options de la page d'accueil"
facebook_url = models.URLField(
null=True,
blank=True,
help_text="Url du compte facebook"
)
twitter_url = models.URLField(
null=True,
blank=True,
help_text="Url du compte twitter"
)
twitter_account_name = models.CharField(
max_length=32,
null=True,
blank=True,
help_text="Nom du compte à afficher"
)
class Meta:
permissions = (
2018-04-16 16:22:51 +00:00
("view_homeoption", "Peut voir les options de l'accueil"),
2018-04-16 03:28:27 +00:00
)
2018-04-16 16:22:51 +00:00
@receiver(post_save, sender=HomeOption)
def homeoption_post_save(**kwargs):
2018-04-16 03:28:27 +00:00
"""Ecriture dans le cache"""
2018-04-16 16:22:51 +00:00
home_pref = kwargs['instance']
home_pref.set_in_cache()
2018-04-16 03:28:27 +00:00
2018-03-28 15:39:23 +00:00
class MailMessageOption(AclMixin, models.Model):
"""Reglages, mail de bienvenue et autre"""
PRETTY_NAME = "Options de corps de mail"
welcome_mail_fr = models.TextField(default="")
welcome_mail_en = models.TextField(default="")
class Meta:
permissions = (
("view_mailmessageoption", "Peut voir les options de mail"),
)