8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-27 07:02:26 +00:00

Add or translate some docstrings in preferences/

This commit is contained in:
Laouen Fernet 2020-04-29 14:23:12 +02:00 committed by Gabriel Detraz
parent 25e4d52615
commit d186449767
3 changed files with 288 additions and 115 deletions

View file

@ -53,7 +53,7 @@ from topologie.models import Switch
class EditOptionalUserForm(ModelForm): class EditOptionalUserForm(ModelForm):
"""Formulaire d'édition des options de l'user. (solde, telephone..)""" """Form used to edit user preferences."""
class Meta: class Meta:
model = OptionalUser model = OptionalUser
@ -82,7 +82,7 @@ class EditOptionalUserForm(ModelForm):
class EditOptionalMachineForm(ModelForm): class EditOptionalMachineForm(ModelForm):
"""Options machines (max de machines, etc)""" """Form used to edit machine preferences."""
class Meta: class Meta:
model = OptionalMachine model = OptionalMachine
@ -105,9 +105,7 @@ class EditOptionalMachineForm(ModelForm):
class EditOptionalTopologieForm(ModelForm): class EditOptionalTopologieForm(ModelForm):
"""Options de topologie, formulaire d'edition (vlan par default etc) """Form used to edit the configuration of switches."""
On rajoute un champ automatic provision switchs pour gérer facilement
l'ajout de switchs au provisionning automatique"""
automatic_provision_switchs = forms.ModelMultipleChoiceField( automatic_provision_switchs = forms.ModelMultipleChoiceField(
Switch.objects.all(), required=False Switch.objects.all(), required=False
@ -135,7 +133,7 @@ class EditOptionalTopologieForm(ModelForm):
class EditGeneralOptionForm(ModelForm): class EditGeneralOptionForm(ModelForm):
"""Options générales (affichages de résultats de recherche, etc)""" """Form used to edit general preferences."""
class Meta: class Meta:
model = GeneralOption model = GeneralOption
@ -165,7 +163,7 @@ class EditGeneralOptionForm(ModelForm):
class EditAssoOptionForm(ModelForm): class EditAssoOptionForm(ModelForm):
"""Options de l'asso (addresse, telephone, etc)""" """Form used to edit information about the organisation."""
class Meta: class Meta:
model = AssoOption model = AssoOption
@ -189,7 +187,7 @@ class EditAssoOptionForm(ModelForm):
class EditMailMessageOptionForm(ModelForm): class EditMailMessageOptionForm(ModelForm):
"""Formulaire d'edition des messages de bienvenue personnalisés""" """Form used to edit welcome email messages."""
class Meta: class Meta:
model = MailMessageOption model = MailMessageOption
@ -207,7 +205,9 @@ class EditMailMessageOptionForm(ModelForm):
class EditHomeOptionForm(ModelForm): class EditHomeOptionForm(ModelForm):
"""Edition forms of Home options""" """Form used to edit the social networks information displayed on the home
page.
"""
class Meta: class Meta:
model = HomeOption model = HomeOption
@ -222,7 +222,7 @@ class EditHomeOptionForm(ModelForm):
class EditRadiusOptionForm(ModelForm): class EditRadiusOptionForm(ModelForm):
"""Edition forms for Radius options""" """Form used to edit RADIUS preferences."""
class Meta: class Meta:
model = RadiusOption model = RadiusOption
@ -242,7 +242,7 @@ class EditRadiusOptionForm(ModelForm):
class EditCotisationsOptionForm(ModelForm): class EditCotisationsOptionForm(ModelForm):
"""Edition forms for Cotisations options""" """Form used to edit subscription preferences."""
class Meta: class Meta:
model = CotisationsOption model = CotisationsOption
@ -250,7 +250,7 @@ class EditCotisationsOptionForm(ModelForm):
class MandateForm(ModelForm): class MandateForm(ModelForm):
"""Edit Mandates""" """Form used to add and edit mandates."""
class Meta: class Meta:
model = Mandate model = Mandate
@ -319,7 +319,7 @@ class MandateForm(ModelForm):
class ServiceForm(ModelForm): class ServiceForm(ModelForm):
"""Edition, ajout de services sur la page d'accueil""" """Form used to add and edit services displayed on the home page."""
class Meta: class Meta:
model = Service model = Service
@ -335,7 +335,8 @@ class ServiceForm(ModelForm):
class DelServiceForm(Form): class DelServiceForm(Form):
"""Suppression de services sur la page d'accueil""" """Form used to delete one or several services displayed on the home page.
"""
services = forms.ModelMultipleChoiceField( services = forms.ModelMultipleChoiceField(
queryset=Service.objects.none(), queryset=Service.objects.none(),
@ -353,7 +354,7 @@ class DelServiceForm(Form):
class ReminderForm(FormRevMixin, ModelForm): class ReminderForm(FormRevMixin, ModelForm):
"""Edition, ajout de services sur la page d'accueil""" """Form used to add and edit reminders."""
class Meta: class Meta:
model = Reminder model = Reminder
@ -365,7 +366,7 @@ class ReminderForm(FormRevMixin, ModelForm):
class RadiusKeyForm(FormRevMixin, ModelForm): class RadiusKeyForm(FormRevMixin, ModelForm):
"""Edition, ajout de clef radius""" """Form used to add and edit RADIUS keys."""
members = forms.ModelMultipleChoiceField( members = forms.ModelMultipleChoiceField(
queryset=Switch.objects.all(), required=False queryset=Switch.objects.all(), required=False
@ -389,8 +390,7 @@ class RadiusKeyForm(FormRevMixin, ModelForm):
class SwitchManagementCredForm(FormRevMixin, ModelForm): class SwitchManagementCredForm(FormRevMixin, ModelForm):
"""Edition, ajout de creds de management pour gestion """Form used to add and edit switch management credentials."""
et interface rest des switchs"""
members = forms.ModelMultipleChoiceField(Switch.objects.all(), required=False) members = forms.ModelMultipleChoiceField(Switch.objects.all(), required=False)
@ -412,7 +412,7 @@ class SwitchManagementCredForm(FormRevMixin, ModelForm):
class MailContactForm(ModelForm): class MailContactForm(ModelForm):
"""Edition, ajout d'adresse de contact""" """Form used to add and edit contact email addresses."""
class Meta: class Meta:
model = MailContact model = MailContact
@ -424,7 +424,7 @@ class MailContactForm(ModelForm):
class DelMailContactForm(Form): class DelMailContactForm(Form):
"""Delete contact email adress""" """Form used to delete one or several contact email addresses."""
mailcontacts = forms.ModelMultipleChoiceField( mailcontacts = forms.ModelMultipleChoiceField(
queryset=MailContact.objects.none(), queryset=MailContact.objects.none(),
@ -442,9 +442,7 @@ class DelMailContactForm(Form):
class DocumentTemplateForm(FormRevMixin, ModelForm): class DocumentTemplateForm(FormRevMixin, ModelForm):
""" """Form used to add and edit document templates."""
Form used to create a document template.
"""
class Meta: class Meta:
model = DocumentTemplate model = DocumentTemplate
@ -456,10 +454,7 @@ class DocumentTemplateForm(FormRevMixin, ModelForm):
class DelDocumentTemplateForm(FormRevMixin, Form): class DelDocumentTemplateForm(FormRevMixin, Form):
""" """Form used to delete one or several document templates."""
Form used to delete one or more document templatess.
The use must choose the one to delete by checking the boxes.
"""
document_templates = forms.ModelMultipleChoiceField( document_templates = forms.ModelMultipleChoiceField(
queryset=DocumentTemplate.objects.none(), queryset=DocumentTemplate.objects.none(),
@ -477,7 +472,7 @@ class DelDocumentTemplateForm(FormRevMixin, Form):
class RadiusAttributeForm(ModelForm): class RadiusAttributeForm(ModelForm):
"""Edit and add RADIUS attributes.""" """Form used to add and edit RADIUS attributes."""
class Meta: class Meta:
model = RadiusAttribute model = RadiusAttribute
@ -489,7 +484,7 @@ class RadiusAttributeForm(ModelForm):
class DelRadiusAttributeForm(Form): class DelRadiusAttributeForm(Form):
"""Delete RADIUS attributes""" """Form used to delete one or several RADIUS attributes."""
attributes = forms.ModelMultipleChoiceField( attributes = forms.ModelMultipleChoiceField(
queryset=RadiusAttribute.objects.none(), queryset=RadiusAttribute.objects.none(),

View file

@ -44,20 +44,22 @@ from datetime import timedelta
class PreferencesModel(models.Model): class PreferencesModel(models.Model):
""" Base object for the Preferences objects """Base object for the Preferences objects.
Defines methods to handle the cache of the settings (they should
not change a lot) """ Defines methods to handle the cache of the settings (they should not change
a lot).
"""
@classmethod @classmethod
def set_in_cache(cls): def set_in_cache(cls):
""" Save the preferences in a server-side cache """ """Save the preferences in a server-side cache."""
instance, _created = cls.objects.get_or_create() instance, _created = cls.objects.get_or_create()
cache.set(cls().__class__.__name__.lower(), instance, None) cache.set(cls().__class__.__name__.lower(), instance, None)
return instance return instance
@classmethod @classmethod
def get_cached_value(cls, key): def get_cached_value(cls, key):
""" Get the preferences from the server-side cache """ """Get the preferences from the server-side cache."""
instance = cache.get(cls().__class__.__name__.lower()) instance = cache.get(cls().__class__.__name__.lower())
if instance is None: if instance is None:
instance = cls.set_in_cache() instance = cls.set_in_cache()
@ -68,8 +70,34 @@ class PreferencesModel(models.Model):
class OptionalUser(AclMixin, PreferencesModel): class OptionalUser(AclMixin, PreferencesModel):
"""Options pour l'user : obligation ou nom du telephone, """User preferences: telephone number requirement, user balance activation,
activation ou non du solde, autorisation du negatif, fingerprint etc""" creation of users by everyone etc.
Attributes:
is_tel_mandatory: whether indicating a telephone number is mandatory.
gpg_fingerprint: whether GPG fingerprints are enabled.
all_can_create_club: whether all users can create a club.
all_can_create_adherent: whether all users can create a member.
shell_default: the default shell for users connecting to machines
managed by the organisation.
self_change_shell: whether users can edit their shell.
self_change_pseudo: whether users can edit their pseudo (username).
self_room_policy: whether users can edit the policy of their room.
local_email_accounts_enabled: whether local email accounts are enabled.
local_email_domain: the domain used for local email accounts.
max_email_address: the maximum number of local email addresses allowed
for a standard user.
delete_notyetactive: the number of days before deleting not yet active
users.
disable_emailnotyetconfirmed: the number of days before disabling users
with not yet verified email address.
self_adhesion: whether users can create their account themselves.
all_users_active: whether newly created users are active.
allow_set_password_during_user_creation: whether users can set their
password directly when creating their account.
allow_archived_connexion: whether archived users can connect on the web
interface.
"""
DISABLED = "DISABLED" DISABLED = "DISABLED"
ONLY_INACTIVE = "ONLY_INACTIVE" ONLY_INACTIVE = "ONLY_INACTIVE"
@ -158,23 +186,32 @@ class OptionalUser(AclMixin, PreferencesModel):
verbose_name = _("user preferences") verbose_name = _("user preferences")
def clean(self): def clean(self):
"""Clean model: """Check the email extension."""
Check the mail_extension
"""
if self.local_email_domain[0] != "@": if self.local_email_domain[0] != "@":
raise ValidationError(_("Email domain must begin with @.")) raise ValidationError(_("Email domain must begin with @."))
@receiver(post_save, sender=OptionalUser) @receiver(post_save, sender=OptionalUser)
def optionaluser_post_save(**kwargs): def optionaluser_post_save(**kwargs):
"""Ecriture dans le cache""" """Write in the cache."""
user_pref = kwargs["instance"] user_pref = kwargs["instance"]
user_pref.set_in_cache() user_pref.set_in_cache()
class OptionalMachine(AclMixin, PreferencesModel): class OptionalMachine(AclMixin, PreferencesModel):
"""Options pour les machines : maximum de machines ou d'alias par user """Machines preferences: maximum number of machines per user, IPv6
sans droit, activation de l'ipv6""" activation etc.
Attributes:
password_machine: whether password per machine is enabled.
max_lambdauser_interfaces: the maximum number of interfaces allowed for
a standard user.
max_lambdauser_aliases: the maximum number of aliases allowed for a
standard user.
ipv6_mode: whether IPv6 mode is enabled.
create_machine: whether creation of machine is enabled.
default_dns_ttl: the default TTL for CNAME, A and AAAA records.
"""
SLAAC = "SLAAC" SLAAC = "SLAAC"
DHCPV6 = "DHCPV6" DHCPV6 = "DHCPV6"
@ -197,7 +234,7 @@ class OptionalMachine(AclMixin, PreferencesModel):
@cached_property @cached_property
def ipv6(self): def ipv6(self):
""" Check if the IPv6 option is activated """ """Check if the IPv6 mode is enabled."""
return not self.get_cached_value("ipv6_mode") == "DISABLED" return not self.get_cached_value("ipv6_mode") == "DISABLED"
class Meta: class Meta:
@ -207,7 +244,7 @@ class OptionalMachine(AclMixin, PreferencesModel):
@receiver(post_save, sender=OptionalMachine) @receiver(post_save, sender=OptionalMachine)
def optionalmachine_post_save(**kwargs): def optionalmachine_post_save(**kwargs):
"""Synchronisation ipv6 et ecriture dans le cache""" """Synchronise IPv6 mode and write in the cache."""
machine_pref = kwargs["instance"] machine_pref = kwargs["instance"]
machine_pref.set_in_cache() machine_pref.set_in_cache()
if machine_pref.ipv6_mode != "DISABLED": if machine_pref.ipv6_mode != "DISABLED":
@ -216,8 +253,21 @@ def optionalmachine_post_save(**kwargs):
class OptionalTopologie(AclMixin, PreferencesModel): class OptionalTopologie(AclMixin, PreferencesModel):
"""Reglages pour la topologie : mode d'accès radius, vlan où placer """Configuration of switches: automatic provision, RADIUS mode, default
les machines en accept ou reject""" VLANs etc.
Attributes:
switchs_web_management: whether web management for automatic provision
is enabled.
switchs_web_management_ssl: whether SSL web management is required.
switchs_rest_management: whether REST management for automatic
provision is enabled.
switchs_ip_type: the IP range for the management of switches.
switchs_provision: the provision mode for switches to get their
configuration.
sftp_login: the SFTP login for switches.
sftp_pass: the SFTP password for switches.
"""
MACHINE = "MACHINE" MACHINE = "MACHINE"
DEFINED = "DEFINED" DEFINED = "DEFINED"
@ -264,7 +314,7 @@ class OptionalTopologie(AclMixin, PreferencesModel):
@cached_property @cached_property
def provisioned_switchs(self): def provisioned_switchs(self):
"""Liste des switches provisionnés""" """Get the list of provisioned switches."""
from topologie.models import Switch from topologie.models import Switch
return Switch.objects.filter(automatic_provision=True).order_by( return Switch.objects.filter(automatic_provision=True).order_by(
@ -273,7 +323,9 @@ class OptionalTopologie(AclMixin, PreferencesModel):
@cached_property @cached_property
def switchs_management_interface(self): def switchs_management_interface(self):
"""Return the ip of the interface that the switch have to contact to get it's config""" """Get the interface that the switch has to contact to get its
configuration.
"""
if self.switchs_ip_type: if self.switchs_ip_type:
from machines.models import Role, Interface from machines.models import Role, Interface
@ -291,14 +343,16 @@ class OptionalTopologie(AclMixin, PreferencesModel):
@cached_property @cached_property
def switchs_management_interface_ip(self): def switchs_management_interface_ip(self):
"""Same, but return the ipv4""" """Get the IPv4 address of the interface that the switch has to contact
to get its configuration.
"""
if not self.switchs_management_interface: if not self.switchs_management_interface:
return None return None
return self.switchs_management_interface.ipv4 return self.switchs_management_interface.ipv4
@cached_property @cached_property
def switchs_management_sftp_creds(self): def switchs_management_sftp_creds(self):
"""Credentials des switchs pour provion sftp""" """Get the switch credentials for SFTP provisioning."""
if self.sftp_login and self.sftp_pass: if self.sftp_login and self.sftp_pass:
return {"login": self.sftp_login, "pass": self.sftp_pass} return {"login": self.sftp_login, "pass": self.sftp_pass}
else: else:
@ -306,7 +360,9 @@ class OptionalTopologie(AclMixin, PreferencesModel):
@cached_property @cached_property
def switchs_management_utils(self): def switchs_management_utils(self):
"""Used for switch_conf, return a list of ip on vlans""" """Get the dictionary of IP addresses for the configuration of
switches.
"""
from machines.models import Role, Ipv6List, Interface from machines.models import Role, Ipv6List, Interface
def return_ips_dict(interfaces): def return_ips_dict(interfaces):
@ -350,8 +406,7 @@ class OptionalTopologie(AclMixin, PreferencesModel):
@cached_property @cached_property
def provision_switchs_enabled(self): def provision_switchs_enabled(self):
"""Return true if all settings are ok : switchs on automatic provision, """Check if all automatic provisioning settings are OK."""
ip_type"""
return bool( return bool(
self.provisioned_switchs self.provisioned_switchs
and self.switchs_ip_type and self.switchs_ip_type
@ -371,13 +426,20 @@ class OptionalTopologie(AclMixin, PreferencesModel):
@receiver(post_save, sender=OptionalTopologie) @receiver(post_save, sender=OptionalTopologie)
def optionaltopologie_post_save(**kwargs): def optionaltopologie_post_save(**kwargs):
"""Ecriture dans le cache""" """Write in the cache."""
topologie_pref = kwargs["instance"] topologie_pref = kwargs["instance"]
topologie_pref.set_in_cache() topologie_pref.set_in_cache()
class RadiusKey(AclMixin, models.Model): class RadiusKey(AclMixin, models.Model):
"""Class of a radius key""" """Class of a RADIUS key.
Attributes:
radius_key: the encrypted RADIUS key.
comment: a comment related to the key.
default_switch: bool, True if the key is to be used by default on
switches and False otherwise.
"""
radius_key = AESEncryptedField(max_length=255, help_text=_("RADIUS key.")) radius_key = AESEncryptedField(max_length=255, help_text=_("RADIUS key."))
comment = models.CharField( comment = models.CharField(
@ -393,9 +455,7 @@ class RadiusKey(AclMixin, models.Model):
verbose_name_plural = _("RADIUS keys") verbose_name_plural = _("RADIUS keys")
def clean(self): def clean(self):
"""Clean model: """Check if there is a unique default RADIUS key."""
Check default switch is unique
"""
if RadiusKey.objects.filter(default_switch=True).count() > 1: if RadiusKey.objects.filter(default_switch=True).count() > 1:
raise ValidationError(_("Default RADIUS key for switches already exists.")) raise ValidationError(_("Default RADIUS key for switches already exists."))
@ -404,7 +464,14 @@ class RadiusKey(AclMixin, models.Model):
class SwitchManagementCred(AclMixin, models.Model): class SwitchManagementCred(AclMixin, models.Model):
"""Class of a management creds of a switch, for rest management""" """Class of a switch management credentials, for rest management.
Attributes:
management_id: the login used to connect to switches.
management_pass: the encrypted password used to connect to switches.
default_switch: bool, True if the credentials are to be used by default
on switches and False otherwise.
"""
management_id = models.CharField(max_length=63, help_text=_("Switch login.")) management_id = models.CharField(max_length=63, help_text=_("Switch login."))
management_pass = AESEncryptedField(max_length=63, help_text=_("Password.")) management_pass = AESEncryptedField(max_length=63, help_text=_("Password."))
@ -426,9 +493,13 @@ class SwitchManagementCred(AclMixin, models.Model):
class Reminder(AclMixin, models.Model): class Reminder(AclMixin, models.Model):
"""Options pour les mails de notification de fin d'adhésion. """Reminder of membership's end preferences: email messages, number of days
Days: liste des nombres de jours pour lesquells un mail est envoyé before sending emails.
optionalMessage: message additionel pour le mail
Attributes:
days: the number of days before the membership's end to send the
reminder.
message: the content of the reminder.
""" """
days = models.IntegerField( days = models.IntegerField(
@ -460,8 +531,26 @@ class Reminder(AclMixin, models.Model):
class GeneralOption(AclMixin, PreferencesModel): class GeneralOption(AclMixin, PreferencesModel):
"""Options générales : nombre de resultats par page, nom du site, """General preferences: number of search results per page, website name
temps les liens sont valides""" etc.
Attributes:
general_message_fr: general message displayed on the French version of
the website (e.g. in case of maintenance).
general_message_en: general message displayed on the English version of
the website (e.g. in case of maintenance).
search_display_page: number of results displayed (in each category)
when searching.
pagination_number: number of items per page (standard size).
pagination_large_number: number of items per page (large size).
req_expire_hrs: number of hours before expiration of the reset password
link.
site_name: website name.
email_from: email address for automatic emailing.
main_site_url: main site URL.
GTU_sum_up: summary of the General Terms of Use.
GTU: file, General Terms of Use.
"""
general_message_fr = models.TextField( general_message_fr = models.TextField(
default="", default="",
@ -496,14 +585,20 @@ class GeneralOption(AclMixin, PreferencesModel):
@receiver(post_save, sender=GeneralOption) @receiver(post_save, sender=GeneralOption)
def generaloption_post_save(**kwargs): def generaloption_post_save(**kwargs):
"""Ecriture dans le cache""" """Write in the cache."""
general_pref = kwargs["instance"] general_pref = kwargs["instance"]
general_pref.set_in_cache() general_pref.set_in_cache()
class Service(AclMixin, models.Model): class Service(AclMixin, models.Model):
"""Liste des services affichés sur la page d'accueil : url, description, """Service displayed on the home page.
image et nom"""
Attributes:
name: the name of the service.
url: the URL of the service.
description: the description of the service.
image: an image to illustrate the service (e.g. logo).
"""
name = models.CharField(max_length=32) name = models.CharField(max_length=32)
url = models.URLField() url = models.URLField()
@ -520,7 +615,12 @@ class Service(AclMixin, models.Model):
class MailContact(AclMixin, models.Model): class MailContact(AclMixin, models.Model):
"""Contact email adress with a commentary.""" """Contact email address with a comment.
Attributes:
address: the contact email address.
commentary: a comment used to describe the contact email address.
"""
address = models.EmailField( address = models.EmailField(
default="contact@example.org", help_text=_("Contact email address.") default="contact@example.org", help_text=_("Contact email address.")
@ -549,6 +649,15 @@ class MailContact(AclMixin, models.Model):
class Mandate(RevMixin, AclMixin, models.Model): class Mandate(RevMixin, AclMixin, models.Model):
"""Mandate, documenting who was the president of the organisation at a
given time.
Attributes:
president: User, the president during the mandate.
start_date: datetime, the date when the mandate started.
end_date: datetime, the date when the mandate ended.
"""
class Meta: class Meta:
verbose_name = _("mandate") verbose_name = _("mandate")
verbose_name_plural = _("mandates") verbose_name_plural = _("mandates")
@ -567,7 +676,14 @@ class Mandate(RevMixin, AclMixin, models.Model):
@classmethod @classmethod
def get_mandate(cls, date=timezone.now): def get_mandate(cls, date=timezone.now):
""""Find the mandate taking place at the given date.""" """"Get the mandate taking place at the given date.
Args:
date: the date used to find the mandate (default: timezone.now).
Returns:
The mandate related to the given date.
"""
if callable(date): if callable(date):
date = date() date = date()
mandate = ( mandate = (
@ -590,7 +706,21 @@ class Mandate(RevMixin, AclMixin, models.Model):
class AssoOption(AclMixin, PreferencesModel): class AssoOption(AclMixin, PreferencesModel):
"""Options générales de l'asso : siret, addresse, nom, etc""" """Information about the organisation: name, address, SIRET number etc.
Attributes:
name: the name of the organisation.
siret: the SIRET number of the organisation.
adresse1: the first line of the organisation's address, e.g. street and
number.
adresse2: the second line of the organisation's address, e.g. city and
postal code.
contact: contact email address.
telephone: contact telephone number.
pseudo: short name of the organisation.
utilisateur_asso: the user used to manage the organisation.
description: the description of the organisation.
"""
name = models.CharField( name = models.CharField(
default=_("Networking organisation school Something"), max_length=256 default=_("Networking organisation school Something"), max_length=256
@ -613,13 +743,20 @@ class AssoOption(AclMixin, PreferencesModel):
@receiver(post_save, sender=AssoOption) @receiver(post_save, sender=AssoOption)
def assooption_post_save(**kwargs): def assooption_post_save(**kwargs):
"""Ecriture dans le cache""" """Write in the cache."""
asso_pref = kwargs["instance"] asso_pref = kwargs["instance"]
asso_pref.set_in_cache() asso_pref.set_in_cache()
class HomeOption(AclMixin, PreferencesModel): class HomeOption(AclMixin, PreferencesModel):
"""Settings of the home page (facebook/twitter etc)""" """Social networks displayed on the home page (supports only Facebook and
Twitter).
Attributes:
facebook_url: URL of the Facebook account.
twitter_url: URL of the Twitter account.
twitter_account_name: name of the Twitter account.
"""
facebook_url = models.URLField(null=True, blank=True) facebook_url = models.URLField(null=True, blank=True)
twitter_url = models.URLField(null=True, blank=True) twitter_url = models.URLField(null=True, blank=True)
@ -632,13 +769,18 @@ class HomeOption(AclMixin, PreferencesModel):
@receiver(post_save, sender=HomeOption) @receiver(post_save, sender=HomeOption)
def homeoption_post_save(**kwargs): def homeoption_post_save(**kwargs):
"""Ecriture dans le cache""" """Write in the cache."""
home_pref = kwargs["instance"] home_pref = kwargs["instance"]
home_pref.set_in_cache() home_pref.set_in_cache()
class MailMessageOption(AclMixin, models.Model): class MailMessageOption(AclMixin, models.Model):
"""Reglages, mail de bienvenue et autre""" """Welcome email messages preferences.
Attributes:
welcome_mail_fr: the text of the welcome email in French.
welcome_mail_en: the text of the welcome email in English.
"""
welcome_mail_fr = models.TextField( welcome_mail_fr = models.TextField(
default="", blank=True, help_text=_("Welcome email in French.") default="", blank=True, help_text=_("Welcome email in French.")
@ -655,6 +797,14 @@ class MailMessageOption(AclMixin, models.Model):
class RadiusAttribute(RevMixin, AclMixin, models.Model): class RadiusAttribute(RevMixin, AclMixin, models.Model):
"""RADIUS attributes preferences.
Attributes:
attribute: the name of the RADIUS attribute.
value: the value of the RADIUS attribute.
comment: the comment to document the attribute.
"""
class Meta: class Meta:
verbose_name = _("RADIUS attribute") verbose_name = _("RADIUS attribute")
verbose_name_plural = _("RADIUS attributes") verbose_name_plural = _("RADIUS attributes")
@ -677,6 +827,30 @@ class RadiusAttribute(RevMixin, AclMixin, models.Model):
class RadiusOption(AclMixin, PreferencesModel): class RadiusOption(AclMixin, PreferencesModel):
"""RADIUS preferences.
Attributes:
radius_general_policy: the general RADIUS policy (MACHINE or DEFINED).
unknown_machine: the RADIUS policy for unknown machines.
unknown_machine_vlan: the VLAN for unknown machines if not rejected.
unknown_machine_attributes: the answer attributes for unknown machines.
unknown_port: the RADIUS policy for unknown ports.
unknown_port_vlan: the VLAN for unknown ports if not rejected;
unknown_port_attributes: the answer attributes for unknown ports.
unknown_room: the RADIUS policy for machines connecting from
unregistered rooms (relevant for ports with STRICT RADIUS mode).
unknown_room_vlan: the VLAN for unknown rooms if not rejected.
unknown_room_attributes: the answer attributes for unknown rooms.
non_member: the RADIUS policy for non members.
non_member_vlan: the VLAN for non members if not rejected.
non_member_attributes: the answer attributes for non members.
banned: the RADIUS policy for banned users.
banned_vlan: the VLAN for banned users if not rejected.
banned_attributes: the answer attributes for banned users.
vlan_decision_ok: the VLAN for accepted machines.
ok_attributes: the answer attributes for accepted machines.
"""
class Meta: class Meta:
verbose_name = _("RADIUS policy") verbose_name = _("RADIUS policy")
verbose_name_plural = _("RADIUS policies") verbose_name_plural = _("RADIUS policies")
@ -847,6 +1021,15 @@ def default_voucher():
class CotisationsOption(AclMixin, PreferencesModel): class CotisationsOption(AclMixin, PreferencesModel):
"""Subscription preferences.
Attributes:
invoice_template: the template for invoices.
voucher_template: the template for vouchers.
send_voucher_mail: whether the voucher is sent by email when the
invoice is controlled.
"""
class Meta: class Meta:
verbose_name = _("subscription preferences") verbose_name = _("subscription preferences")
@ -877,6 +1060,10 @@ class CotisationsOption(AclMixin, PreferencesModel):
class DocumentTemplate(RevMixin, AclMixin, models.Model): class DocumentTemplate(RevMixin, AclMixin, models.Model):
"""Represent a template in order to create documents such as invoice or """Represent a template in order to create documents such as invoice or
subscription voucher. subscription voucher.
Attributes:
template: file, the template used to create documents.
name: the name of the template.
""" """
template = models.FileField(upload_to="templates/", verbose_name=_("template")) template = models.FileField(upload_to="templates/", verbose_name=_("template"))
@ -892,9 +1079,8 @@ class DocumentTemplate(RevMixin, AclMixin, models.Model):
@receiver(models.signals.post_delete, sender=DocumentTemplate) @receiver(models.signals.post_delete, sender=DocumentTemplate)
def auto_delete_file_on_delete(sender, instance, **kwargs): def auto_delete_file_on_delete(sender, instance, **kwargs):
""" """Delete the tempalte file from filesystem when the related
Deletes file from filesystem DocumentTemplate object is deleted.
when corresponding `DocumentTemplate` object is deleted.
""" """
if instance.template: if instance.template:
if os.path.isfile(instance.template.path): if os.path.isfile(instance.template.path):
@ -903,10 +1089,8 @@ def auto_delete_file_on_delete(sender, instance, **kwargs):
@receiver(models.signals.pre_save, sender=DocumentTemplate) @receiver(models.signals.pre_save, sender=DocumentTemplate)
def auto_delete_file_on_change(sender, instance, **kwargs): def auto_delete_file_on_change(sender, instance, **kwargs):
""" """Delete the previous file from filesystem when the related
Deletes old file from filesystem DocumentTemplate object is updated with new file.
when corresponding `DocumentTemplate` object is updated
with new file.
""" """
if not instance.pk: if not instance.pk:
return False return False

View file

@ -24,8 +24,8 @@
# Gabriel Détraz, Augustin Lemesle # Gabriel Détraz, Augustin Lemesle
# Gplv2 # Gplv2
""" """
Vue d'affichage, et de modification des réglages (réglages machine, Views to display and edit settings (preferences of machines, users, topology,
topologie, users, service...) services etc.)
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
@ -88,7 +88,7 @@ from . import forms
def edit_options_template_function(request, section, forms, models): def edit_options_template_function(request, section, forms, models):
""" Edition des préférences générales""" """View used to edit general preferences."""
model = getattr(models, section, None) model = getattr(models, section, None)
form_instance = getattr(forms, "Edit" + section + "Form", None) form_instance = getattr(forms, "Edit" + section + "Form", None)
if not (model or form_instance): if not (model or form_instance):
@ -127,8 +127,7 @@ def edit_options_template_function(request, section, forms, models):
HomeOption, HomeOption,
) )
def display_options(request): def display_options(request):
"""Vue pour affichage des options (en vrac) classé selon les models """View used to display preferences sorted by model."""
correspondants dans un tableau"""
useroptions, _created = OptionalUser.objects.get_or_create() useroptions, _created = OptionalUser.objects.get_or_create()
machineoptions, _created = OptionalMachine.objects.get_or_create() machineoptions, _created = OptionalMachine.objects.get_or_create()
topologieoptions, _created = OptionalTopologie.objects.get_or_create() topologieoptions, _created = OptionalTopologie.objects.get_or_create()
@ -188,7 +187,7 @@ def edit_options(request, section):
@login_required @login_required
@can_create(Service) @can_create(Service)
def add_service(request): def add_service(request):
"""Ajout d'un service de la page d'accueil""" """View used to add services displayed on the home page."""
service = ServiceForm(request.POST or None, request.FILES or None) service = ServiceForm(request.POST or None, request.FILES or None)
if service.is_valid(): if service.is_valid():
service.save() service.save()
@ -204,7 +203,7 @@ def add_service(request):
@login_required @login_required
@can_edit(Service) @can_edit(Service)
def edit_service(request, service_instance, **_kwargs): def edit_service(request, service_instance, **_kwargs):
"""Edition des services affichés sur la page d'accueil""" """View used to edit services displayed on the home page."""
service = ServiceForm( service = ServiceForm(
request.POST or None, request.FILES or None, instance=service_instance request.POST or None, request.FILES or None, instance=service_instance
) )
@ -222,7 +221,7 @@ def edit_service(request, service_instance, **_kwargs):
@login_required @login_required
@can_delete(Service) @can_delete(Service)
def del_service(request, service_instance, **_kwargs): def del_service(request, service_instance, **_kwargs):
"""Suppression d'un service de la page d'accueil""" """View used to delete services displayed on the home page."""
if request.method == "POST": if request.method == "POST":
service_instance.delete() service_instance.delete()
messages.success(request, _("The service was deleted.")) messages.success(request, _("The service was deleted."))
@ -237,7 +236,7 @@ def del_service(request, service_instance, **_kwargs):
@login_required @login_required
@can_create(Reminder) @can_create(Reminder)
def add_reminder(request): def add_reminder(request):
"""Ajout d'un mail de rappel""" """View used to add reminders."""
reminder = ReminderForm(request.POST or None, request.FILES or None) reminder = ReminderForm(request.POST or None, request.FILES or None)
if reminder.is_valid(): if reminder.is_valid():
reminder.save() reminder.save()
@ -253,7 +252,7 @@ def add_reminder(request):
@login_required @login_required
@can_edit(Reminder) @can_edit(Reminder)
def edit_reminder(request, reminder_instance, **_kwargs): def edit_reminder(request, reminder_instance, **_kwargs):
"""Edition reminder""" """View used to edit reminders."""
reminder = ReminderForm( reminder = ReminderForm(
request.POST or None, request.FILES or None, instance=reminder_instance request.POST or None, request.FILES or None, instance=reminder_instance
) )
@ -271,7 +270,7 @@ def edit_reminder(request, reminder_instance, **_kwargs):
@login_required @login_required
@can_delete(Reminder) @can_delete(Reminder)
def del_reminder(request, reminder_instance, **_kwargs): def del_reminder(request, reminder_instance, **_kwargs):
"""Destruction d'un reminder""" """View used to delete reminders."""
if request.method == "POST": if request.method == "POST":
reminder_instance.delete() reminder_instance.delete()
messages.success(request, _("The reminder was deleted.")) messages.success(request, _("The reminder was deleted."))
@ -286,7 +285,7 @@ def del_reminder(request, reminder_instance, **_kwargs):
@login_required @login_required
@can_create(RadiusKey) @can_create(RadiusKey)
def add_radiuskey(request): def add_radiuskey(request):
"""Ajout d'une clef radius""" """View used to add RADIUS keys."""
radiuskey = RadiusKeyForm(request.POST or None) radiuskey = RadiusKeyForm(request.POST or None)
if radiuskey.is_valid(): if radiuskey.is_valid():
radiuskey.save() radiuskey.save()
@ -301,7 +300,7 @@ def add_radiuskey(request):
@can_edit(RadiusKey) @can_edit(RadiusKey)
def edit_radiuskey(request, radiuskey_instance, **_kwargs): def edit_radiuskey(request, radiuskey_instance, **_kwargs):
"""Edition des clefs radius""" """View used to edit RADIUS keys."""
radiuskey = RadiusKeyForm(request.POST or None, instance=radiuskey_instance) radiuskey = RadiusKeyForm(request.POST or None, instance=radiuskey_instance)
if radiuskey.is_valid(): if radiuskey.is_valid():
radiuskey.save() radiuskey.save()
@ -317,7 +316,7 @@ def edit_radiuskey(request, radiuskey_instance, **_kwargs):
@login_required @login_required
@can_delete(RadiusKey) @can_delete(RadiusKey)
def del_radiuskey(request, radiuskey_instance, **_kwargs): def del_radiuskey(request, radiuskey_instance, **_kwargs):
"""Destruction d'un radiuskey""" """View used to delete RADIUS keys."""
if request.method == "POST": if request.method == "POST":
try: try:
radiuskey_instance.delete() radiuskey_instance.delete()
@ -342,6 +341,7 @@ def del_radiuskey(request, radiuskey_instance, **_kwargs):
@can_create(SwitchManagementCred) @can_create(SwitchManagementCred)
def add_switchmanagementcred(request): def add_switchmanagementcred(request):
"""Ajout de creds de management""" """Ajout de creds de management"""
"""View used to add switch management credentials."""
switchmanagementcred = SwitchManagementCredForm(request.POST or None) switchmanagementcred = SwitchManagementCredForm(request.POST or None)
if switchmanagementcred.is_valid(): if switchmanagementcred.is_valid():
switchmanagementcred.save() switchmanagementcred.save()
@ -356,7 +356,7 @@ def add_switchmanagementcred(request):
@can_edit(SwitchManagementCred) @can_edit(SwitchManagementCred)
def edit_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs): def edit_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs):
"""Edition des creds de management""" """View used to edit switch management credentials."""
switchmanagementcred = SwitchManagementCredForm( switchmanagementcred = SwitchManagementCredForm(
request.POST or None, instance=switchmanagementcred_instance request.POST or None, instance=switchmanagementcred_instance
) )
@ -374,7 +374,7 @@ def edit_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs)
@login_required @login_required
@can_delete(SwitchManagementCred) @can_delete(SwitchManagementCred)
def del_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs): def del_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs):
"""Destruction d'un switchmanagementcred""" """View used to delete switch management credentials."""
if request.method == "POST": if request.method == "POST":
try: try:
switchmanagementcred_instance.delete() switchmanagementcred_instance.delete()
@ -404,7 +404,7 @@ def del_switchmanagementcred(request, switchmanagementcred_instance, **_kwargs):
@login_required @login_required
@can_create(MailContact) @can_create(MailContact)
def add_mailcontact(request): def add_mailcontact(request):
"""Add a contact email adress.""" """View used to add contact email addresses."""
mailcontact = MailContactForm(request.POST or None, request.FILES or None) mailcontact = MailContactForm(request.POST or None, request.FILES or None)
if mailcontact.is_valid(): if mailcontact.is_valid():
mailcontact.save() mailcontact.save()
@ -420,7 +420,7 @@ def add_mailcontact(request):
@login_required @login_required
@can_edit(MailContact) @can_edit(MailContact)
def edit_mailcontact(request, mailcontact_instance, **_kwargs): def edit_mailcontact(request, mailcontact_instance, **_kwargs):
"""Edit contact email adress.""" """View used to edit contact email addresses."""
mailcontact = MailContactForm( mailcontact = MailContactForm(
request.POST or None, request.FILES or None, instance=mailcontact_instance request.POST or None, request.FILES or None, instance=mailcontact_instance
) )
@ -438,7 +438,7 @@ def edit_mailcontact(request, mailcontact_instance, **_kwargs):
@login_required @login_required
@can_delete_set(MailContact) @can_delete_set(MailContact)
def del_mailcontact(request, instances): def del_mailcontact(request, instances):
"""Delete an email adress""" """View used to delete one or several contact email addresses."""
mailcontacts = DelMailContactForm(request.POST or None, instances=instances) mailcontacts = DelMailContactForm(request.POST or None, instances=instances)
if mailcontacts.is_valid(): if mailcontacts.is_valid():
mailcontacts_dels = mailcontacts.cleaned_data["mailcontacts"] mailcontacts_dels = mailcontacts.cleaned_data["mailcontacts"]
@ -456,9 +456,7 @@ def del_mailcontact(request, instances):
@login_required @login_required
@can_create(DocumentTemplate) @can_create(DocumentTemplate)
def add_document_template(request): def add_document_template(request):
""" """View used to add document templates."""
View used to add a document template.
"""
document_template = DocumentTemplateForm( document_template = DocumentTemplateForm(
request.POST or None, request.FILES or None request.POST or None, request.FILES or None
) )
@ -480,9 +478,7 @@ def add_document_template(request):
@login_required @login_required
@can_edit(DocumentTemplate) @can_edit(DocumentTemplate)
def edit_document_template(request, document_template_instance, **_kwargs): def edit_document_template(request, document_template_instance, **_kwargs):
""" """View used to edit document templates."""
View used to edit a document_template.
"""
document_template = DocumentTemplateForm( document_template = DocumentTemplateForm(
request.POST or None, request.FILES or None, instance=document_template_instance request.POST or None, request.FILES or None, instance=document_template_instance
) )
@ -505,9 +501,7 @@ def edit_document_template(request, document_template_instance, **_kwargs):
@login_required @login_required
@can_delete_set(DocumentTemplate) @can_delete_set(DocumentTemplate)
def del_document_template(request, instances): def del_document_template(request, instances):
""" """View used to delete one or several document templates."""
View used to delete a set of document template.
"""
document_template = DelDocumentTemplateForm( document_template = DelDocumentTemplateForm(
request.POST or None, instances=instances request.POST or None, instances=instances
) )
@ -545,7 +539,7 @@ def del_document_template(request, instances):
@login_required @login_required
@can_create(RadiusAttribute) @can_create(RadiusAttribute)
def add_radiusattribute(request): def add_radiusattribute(request):
"""Create a RADIUS attribute.""" """View used to add RADIUS attributes."""
attribute = RadiusAttributeForm(request.POST or None) attribute = RadiusAttributeForm(request.POST or None)
if attribute.is_valid(): if attribute.is_valid():
attribute.save() attribute.save()
@ -561,7 +555,7 @@ def add_radiusattribute(request):
@login_required @login_required
@can_edit(RadiusAttribute) @can_edit(RadiusAttribute)
def edit_radiusattribute(request, radiusattribute_instance, **_kwargs): def edit_radiusattribute(request, radiusattribute_instance, **_kwargs):
"""Edit a RADIUS attribute.""" """View used to edit RADIUS attributes."""
attribute = RadiusAttributeForm( attribute = RadiusAttributeForm(
request.POST or None, instance=radiusattribute_instance request.POST or None, instance=radiusattribute_instance
) )
@ -579,7 +573,7 @@ def edit_radiusattribute(request, radiusattribute_instance, **_kwargs):
@login_required @login_required
@can_delete(RadiusAttribute) @can_delete(RadiusAttribute)
def del_radiusattribute(request, radiusattribute_instance, **_kwargs): def del_radiusattribute(request, radiusattribute_instance, **_kwargs):
"""Delete a RADIUS attribute.""" """View used to delete RADIUS attributes."""
if request.method == "POST": if request.method == "POST":
radiusattribute_instance.delete() radiusattribute_instance.delete()
messages.success(request, _("The attribute was deleted.")) messages.success(request, _("The attribute was deleted."))
@ -594,7 +588,7 @@ def del_radiusattribute(request, radiusattribute_instance, **_kwargs):
@login_required @login_required
@can_create(Mandate) @can_create(Mandate)
def add_mandate(request): def add_mandate(request):
"""Create a mandate.""" """View used to add mandates."""
mandate = MandateForm(request.POST or None) mandate = MandateForm(request.POST or None)
if mandate.is_valid(): if mandate.is_valid():
mandate.save() mandate.save()
@ -610,7 +604,7 @@ def add_mandate(request):
@login_required @login_required
@can_edit(Mandate) @can_edit(Mandate)
def edit_mandate(request, mandate_instance, **_kwargs): def edit_mandate(request, mandate_instance, **_kwargs):
"""Edit a mandate.""" """View used to edit mandates."""
mandate = MandateForm(request.POST or None, instance=mandate_instance) mandate = MandateForm(request.POST or None, instance=mandate_instance)
if mandate.is_valid(): if mandate.is_valid():
mandate.save() mandate.save()
@ -626,7 +620,7 @@ def edit_mandate(request, mandate_instance, **_kwargs):
@login_required @login_required
@can_delete(Mandate) @can_delete(Mandate)
def del_mandate(request, mandate_instance, **_kwargs): def del_mandate(request, mandate_instance, **_kwargs):
"""Delete a mandate.""" """View used to delete mandates."""
if request.method == "POST": if request.method == "POST":
mandate_instance.delete() mandate_instance.delete()
messages.success(request, _("The mandate was deleted.")) messages.success(request, _("The mandate was deleted."))