Commit 43fb83ec authored by Maël Kervella's avatar Maël Kervella

Cleanup for local email accounts

parent bd19b279
......@@ -492,12 +492,11 @@ class UserSerializer(NamespacedHMSerializer):
"""
access = serializers.BooleanField(source='has_access')
uid = serializers.IntegerField(source='uid_number')
email = serializers.CharField(source='get_mail')
class Meta:
model = users.User
fields = ('name', 'pseudo', 'email', 'school', 'shell', 'comment',
'external_mail', 'redirection', 'internal_address',
fields = ('surname', 'pseudo', 'email', 'local_email_redirect',
'local_email_enabled', 'school', 'shell', 'comment',
'state', 'registered', 'telephone', 'solde', 'access',
'end_access', 'uid', 'class_name', 'api_url')
extra_kwargs = {
......@@ -511,12 +510,11 @@ class ClubSerializer(NamespacedHMSerializer):
name = serializers.CharField(source='surname')
access = serializers.BooleanField(source='has_access')
uid = serializers.IntegerField(source='uid_number')
email = serializers.CharField(source='get_mail')
class Meta:
model = users.Club
fields = ('name', 'pseudo', 'email', 'school', 'shell', 'comment',
'external_mail', 'redirection', 'internal_address',
fields = ('name', 'pseudo', 'email', 'local_email_redirect',
'local_email_enabled', 'school', 'shell', 'comment',
'state', 'registered', 'telephone', 'solde', 'room',
'access', 'end_access', 'administrators', 'members',
'mailing', 'uid', 'api_url')
......@@ -530,14 +528,13 @@ class AdherentSerializer(NamespacedHMSerializer):
"""
access = serializers.BooleanField(source='has_access')
uid = serializers.IntegerField(source='uid_number')
email = serializers.CharField(source='get_mail')
class Meta:
model = users.Adherent
fields = ('name', 'surname', 'pseudo', 'email', 'redirection', 'internal_address',
'external_mail', 'school', 'shell',
'comment', 'state', 'registered', 'telephone', 'room',
'solde', 'access', 'end_access', 'uid', 'api_url')
fields = ('name', 'surname', 'pseudo', 'email', 'local_email_redirect',
'local_email_enabled', 'school', 'shell', 'comment',
'state', 'registered', 'telephone', 'room', 'solde',
'access', 'end_access', 'uid', 'api_url')
extra_kwargs = {
'shell': {'view_name': 'shell-detail'}
}
......@@ -599,16 +596,13 @@ class WhitelistSerializer(NamespacedHMSerializer):
fields = ('user', 'raison', 'date_start', 'date_end', 'active', 'api_url')
class MailAliasSerializer(NamespacedHMSerializer):
"""Serialize `users.models.MailAlias` objects.
class LocalEmailAccountSerializer(NamespacedHMSerializer):
"""Serialize `users.models.LocalEmailAccount` objects.
"""
class Meta:
model = users.MailAlias
fields = ('user', 'valeur', 'complete_mail')
model = users.LocalEmailAccount
fields = ('user', 'local_part', 'complete_email_address', 'api_url')
# SERVICE REGEN
......@@ -627,17 +621,21 @@ class ServiceRegenSerializer(NamespacedHMSerializer):
extra_kwargs = {
'api_url': {'view_name': 'serviceregen-detail'}
}
# Configuration mail
class UserMailAliasSerializer(NamespacedHMSerializer):
get_mail_aliases = MailAliasSerializer(read_only=True, many=True)
# LOCAL EMAILS
class LocalEmailUsersSerializer(NamespacedHMSerializer):
local_email_accounts = LocalEmailAccountSerializer(
read_only=True,
many=True
)
class Meta:
model = users.User
fields = ('pseudo', 'get_mail_aliases')
fields = ('local_email_enabled', 'local_email_redirect',
'local_email_accounts')
# DHCP
......
......@@ -93,13 +93,13 @@ router.register_viewset(r'users/listright', views.ListRightViewSet)
router.register_viewset(r'users/shell', views.ShellViewSet, base_name='shell')
router.register_viewset(r'users/ban', views.BanViewSet)
router.register_viewset(r'users/whitelist', views.WhitelistViewSet)
router.register_viewset(r'users/mailalias', views.MailAliasViewSet)
router.register_viewset(r'users/localemailaccount', views.LocalEmailAccountViewSet)
# SERVICE REGEN
router.register_viewset(r'services/regen', views.ServiceRegenViewSet, base_name='serviceregen')
# DHCP
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
# Mail config
router.register_view(r'mail/alias', views.UserMailAliasView),
# LOCAL EMAILS
router.register_view(r'localemail/users', views.LocalEmailUsersView),
# DNS
router.register_view(r'dns/zones', views.DNSZonesView),
# MAILING
......
......@@ -469,11 +469,19 @@ class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = serializers.WhitelistSerializer
class MailAliasViewSet(viewsets.ReadOnlyModelViewSet):
"""Exposes list and details of `users.models.MailAlias` objects.
class LocalEmailAccountViewSet(viewsets.ReadOnlyModelViewSet):
"""Exposes list and details of `users.models.LocalEmailAccount` objects.
"""
queryset = users.MailAlias.objects.all()
serializer_class = serializers.MailAliasSerializer
serializer_class = serializers.LocalEmailAccountSerializer
queryset = users.LocalEmailAccount.objects.none()
def get_queryset(self):
if preferences.OptionalUser.get_cached_value(
'local_email_accounts_enabled'):
return (users.LocalEmailAccount.objects
.filter(user__local_email_enabled=True))
else:
return users.LocalEmailAccount.objects.none()
# SERVICE REGEN
......@@ -496,19 +504,26 @@ class ServiceRegenViewSet(viewsets.ModelViewSet):
return queryset
# Server mail config
# LOCAL EMAILS
class UserMailAliasView(generics.ListAPIView):
"""Expose all the aliases of the users that activated the internal address
class LocalEmailUsersView(generics.ListAPIView):
"""Exposes all the aliases of the users that activated the internal address
"""
serializer_class = serializers.LocalEmailUsersSerializer
queryset = users.User.objects.filter(internal_address=True)
serializer_class = serializers.UserMailAliasSerializer
def get_queryset(self):
if preferences.OptionalUser.get_cached_value(
'local_email_accounts_enabled'):
return (users.User.objects
.filter(local_email_enabled=True))
else:
return users.User.objects.none()
# DHCP
class HostMacIpView(generics.ListAPIView):
"""Exposes the associations between hostname, mac address and IPv4 in
order to build the DHCP lease files.
......@@ -519,6 +534,7 @@ class HostMacIpView(generics.ListAPIView):
# DNS
class DNSZonesView(generics.ListAPIView):
"""Exposes the detailed information about each extension (hostnames,
IPs, DNS records, etc.) in order to build the DNS zone files.
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-29 16:01
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0035_optionaluser_mail_extension'),
]
operations = [
migrations.AddField(
model_name='optionaluser',
name='mail_accounts',
field=models.BooleanField(default=False, help_text='Enable mail accounts for users'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-30 12:32
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0036_optionaluser_mail_accounts'),
]
operations = [
migrations.AddField(
model_name='optionaluser',
name='max_mail_alias',
field=models.IntegerField(default=15, help_text="Max alias mail for a lambda user"),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-07-23 12:13
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('preferences', '0037_optionaluser_max_mail_alias'),
('preferences', '0045_remove_unused_payment_fields'),
]
operations = [
]
......@@ -8,13 +8,23 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('preferences', '0034_auto_20180416_1120'),
('preferences', '0045_remove_unused_payment_fields'),
]
operations = [
migrations.AddField(
model_name='optionaluser',
name='mail_extension',
field=models.CharField(default='@example.org', help_text='Main extension for internal address', max_length=32),
name='local_email_accounts_enabled',
field=models.BooleanField(default=False, help_text='Enable local email accounts for users'),
),
migrations.AddField(
model_name='optionaluser',
name='local_email_domain',
field=models.CharField(default='@example.org', help_text='Domain to use for local email accounts', max_length=32),
),
migrations.AddField(
model_name='optionaluser',
name='max_local_email_accounts',
field=models.IntegerField(default=15, help_text='Maximum number of local email accounts for a standard user'),
),
]
......@@ -30,9 +30,8 @@ from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.cache import cache
from django.forms import ValidationError
import cotisations.models
import machines.models
from re2o.mixins import AclMixin
......@@ -85,18 +84,18 @@ class OptionalUser(AclMixin, PreferencesModel):
blank=True,
null=True
)
mail_accounts = models.BooleanField(
local_email_accounts_enabled = models.BooleanField(
default=False,
help_text="Enable mail accounts for users"
help_text="Enable local email accounts for users"
)
mail_extension = models.CharField(
local_email_domain = models.CharField(
max_length = 32,
default = "@example.org",
help_text="Main extension for internal address",
help_text="Domain to use for local email accounts",
)
max_mail_alias = models.IntegerField(
max_local_email_accounts = models.IntegerField(
default = 15,
help_text = "Max alias mail for a lambda user"
help_text = "Maximum number of local email accounts for a standard user"
)
class Meta:
......@@ -108,9 +107,9 @@ class OptionalUser(AclMixin, PreferencesModel):
"""Clean model:
Check the mail_extension
"""
if self.mail_extension[0] != "@":
raise ValidationError("Mail extension must begin with @")
if self.local_email_domain[0] != "@":
raise ValidationError("Mail domain must begin with @")
@receiver(post_save, sender=OptionalUser)
def optionaluser_post_save(**kwargs):
......
......@@ -32,206 +32,204 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% block content %}
<h4>Préférences utilisateur</h4>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalUser' %}">
<i class="fa fa-edit"></i>
Editer
</a>
<p>
</p>
<h5>Généralités</h5>
<table class="table table-striped">
<tr>
<th>Téléphone obligatoirement requis</th>
<td>{{ useroptions.is_tel_mandatory|tick }}</td>
<th>Auto inscription</th>
<td>{{ useroptions.self_adhesion|tick }}</td>
</tr>
<tr>
<th>Champ gpg fingerprint</th>
<td>{{ useroptions.gpg_fingerprint|tick }}</td>
<th>Shell par défaut des utilisateurs</th>
<td>{{ useroptions.shell_default }}</td>
</tr>
<tr>
<th>Creations d'adhérents par tous</th>
<td>{{ useroptions.all_can_create_adherent|tick }}</td>
<th>Creations de clubs par tous</th>
<td>{{ useroptions.all_can_create_club|tick }}</td>
</tr>
<h5>{% if useroptions.mail_accounts %}<span class="label label-success">Comptes mails{% else %}<span class="label label-danger">Comptes mails{% endif%}</span></h5>
<table class="table table-striped">
<tr>
<th>Gestion des comptes mails</th>
<td>{{ useroptions.mail_accounts }}</td>
<th>Extension mail interne</th>
<td>{{ useroptions.mail_extension }}</td>
</tr>
<tr>
<th>Nombre d'alias maximum</th>
<td>{{ useroption.max_mail_alias }}<td>
</tr>
</table>
<h4>Préférences machines</h4>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalMachine' %}">
<i class="fa fa-edit"></i>
Editer
</a>
<p>
</p>
<table class="table table-striped">
<tr>
<th>Mot de passe par machine</th>
<td>{{ machineoptions.password_machine|tick }}</td>
<th>Machines/interfaces autorisées par utilisateurs</th>
<td>{{ machineoptions.max_lambdauser_interfaces }}</td>
</tr>
<tr>
<th>Alias dns autorisé par utilisateur</th>
<td>{{ machineoptions.max_lambdauser_aliases }}</td>
<th>Support de l'ipv6</th>
<td>{{ machineoptions.ipv6_mode }}</td>
</tr>
<tr>
<th>Creation de machines</th>
<td>{{ machineoptions.create_machine|tick }}</td>
</tr>
<i class="fa fa-edit"></i> Editer
</a>
<h5>Généralités</h5>
<table class="table table-striped">
<tr>
<th>Téléphone obligatoirement requis</th>
<td>{{ useroptions.is_tel_mandatory|tick }}</td>
<th>Auto inscription</th>
<td>{{ useroptions.self_adhesion|tick }}</td>
</tr>
<tr>
<th>Champ gpg fingerprint</th>
<td>{{ useroptions.gpg_fingerprint|tick }}</td>
<th>Shell par défaut des utilisateurs</th>
<td>{{ useroptions.shell_default }}</td>
</tr>
<tr>
<th>Creations d'adhérents par tous</th>
<td>{{ useroptions.all_can_create_adherent|tick }}</td>
<th>Creations de clubs par tous</th>
<td>{{ useroptions.all_can_create_club|tick }}</td>
</tr>
</table>
<h5>Comptes mails</h5>
<table class="table table-striped">
<tr>
<th>Gestion des comptes mails</th>
<td>{{ useroptions.local_email_accounts_enabled | tick }}</td>
<th>Extension mail interne</th>
<td>{{ useroptions.local_email_domain }}</td>
</tr>
<tr>
<th>Nombre de comptes maximum</th>
<td>{{ useroptions.max_local_email_accounts }}</td>
</tr>
</table>
<h4>Préférences machines</h4>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalMachine' %}">
<i class="fa fa-edit"></i> Editer
</a>
<table class="table table-striped">
<tr>
<th>Mot de passe par machine</th>
<td>{{ machineoptions.password_machine|tick }}</td>
<th>Machines/interfaces autorisées par utilisateurs</th>
<td>{{ machineoptions.max_lambdauser_interfaces }}</td>
</tr>
<tr>
<th>Alias dns autorisé par utilisateur</th>
<td>{{ machineoptions.max_lambdauser_aliases }}</td>
<th>Support de l'ipv6</th>
<td>{{ machineoptions.ipv6_mode }}</td>
</tr>
<tr>
<th>Creation de machines</th>
<td>{{ machineoptions.create_machine|tick }}</td>
</tr>
</table>
<h4>Préférences topologie</h4>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalTopologie' %}">
<i class="fa fa-edit"></i>
Editer
<i class="fa fa-edit"></i> Editer
</a>
<p>
</p>
<table class="table table-striped">
<tr>
<th>Politique générale de placement de vlan</th>
<td>{{ topologieoptions.radius_general_policy }}</td>
<th> Ce réglage défini la politique vlan après acceptation radius : soit sur le vlan de la plage d'ip de la machine, soit sur un vlan prédéfini dans "Vlan où placer les machines après acceptation RADIUS"</th>
<td></td>
</tr>
<tr>
<th>Vlan où placer les machines après acceptation RADIUS</th>
<td>{{ topologieoptions.vlan_decision_ok }}</td>
<th>Vlan où placer les machines après rejet RADIUS</th>
<td>{{ topologieoptions.vlan_decision_nok }}</td>
</tr>
<tr>
<th>Politique générale de placement de vlan</th>
<td>{{ topologieoptions.radius_general_policy }}</td>
<th>
Ce réglage défini la politique vlan après acceptation radius :
soit sur le vlan de la plage d'ip de la machine, soit sur un
vlan prédéfini dans "Vlan où placer les machines après acceptation
RADIUS"
</th>
<td></td>
</tr>
<tr>
<th>Vlan où placer les machines après acceptation RADIUS</th>
<td>{{ topologieoptions.vlan_decision_ok }}</td>
<th>Vlan où placer les machines après rejet RADIUS</th>
<td>{{ topologieoptions.vlan_decision_nok }}</td>
</tr>
</table>
<h4>Préférences generales</h4>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'GeneralOption' %}">
<i class="fa fa-edit"></i>
Editer
<i class="fa fa-edit"></i> Editer
</a>
<p>
</p>
<table class="table table-striped">
<tr>
<th>Nom du site web</th>
<td>{{ generaloptions.site_name }}</td>
<th>Adresse mail d'expedition automatique</th>
<td>{{ generaloptions.email_from }}</td>
</tr>
<tr>
<th>Affichage de résultats dans le champ de recherche</th>
<td>{{ generaloptions.search_display_page }}</td>
<th>Nombre d'items affichés en liste (taille normale)</th>
<td>{{ generaloptions.pagination_number }}</td>
</tr>
<tr>
<th>Nombre d'items affichés en liste (taille élevée)</th>
<td>{{ generaloptions.pagination_large_number }}</td>
<th>Temps avant expiration du lien de reinitialisation de mot de passe (en heures)</th>
<td>{{ generaloptions.req_expire_hrs }}</td>
</tr>
<tr>
<th>Message global affiché sur le site</th>
<td>{{ generaloptions.general_message }}</td>
<th>Résumé des CGU</th>
<td>{{ generaloptions.GTU_sum_up }}</td>
<tr>
<tr>
<th>CGU</th>
<td>{{generaloptions.GTU}}</th>
</tr>
<tr>
<th>Nom du site web</th>
<td>{{ generaloptions.site_name }}</td>
<th>Adresse mail d'expedition automatique</th>
<td>{{ generaloptions.email_from }}</td>
</tr>
<tr>
<th>Affichage de résultats dans le champ de recherche</th>
<td>{{ generaloptions.search_display_page }}</td>
<th>Nombre d'items affichés en liste (taille normale)</th>
<td>{{ generaloptions.pagination_number }}</td>
</tr>
<tr>
<th>Nombre d'items affichés en liste (taille élevée)</th>
<td>{{ generaloptions.pagination_large_number }}</td>
<th>Temps avant expiration du lien de reinitialisation de mot de passe (en heures)</th>
<td>{{ generaloptions.req_expire_hrs }}</td>
</tr>
<tr>
<th>Message global affiché sur le site</th>
<td>{{ generaloptions.general_message }}</td>
<th>Résumé des CGU</th>
<td>{{ generaloptions.GTU_sum_up }}</td>
<tr>
<tr>
<th>CGU</th>
<td>{{generaloptions.GTU}}</th>
</tr>
</table>
<h4>Données de l'association</h4>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'AssoOption' %}">
<i class="fa fa-edit"></i>
Editer
<i class="fa fa-edit"></i> Editer
</a>
<p>
</p>
<table class="table table-striped">
<tr>
<th>Nom</th>
<td>{{ assooptions.name }}</td>
<th>SIRET</th>
<td>{{ assooptions.siret }}</td>
</tr>
<tr>
<th>Adresse</th>
<td>{{ assooptions.adresse1 }}<br>
{{ assooptions.adresse2 }}</td>
<th>Contact mail</th>
<td>{{ assooptions.contact }}</td>
</tr>
<tr>
<th>Telephone</th>
<td>{{ assooptions.telephone }}</td>
<th>Pseudo d'usage</th>
<td>{{ assooptions.pseudo }}</td>
</tr>
<tr>
<th>Objet utilisateur de l'association</th>
<td>{{ assooptions.utilisateur_asso }}</td>
<th>Description de l'association</th>
<td>{{ assooptions.description | safe }}</td>
</tr>
<tr>
<th>Nom</th>
<td>{{ assooptions.name }}</td>
<th>SIRET</th>
<td>{{ assooptions.siret }}</td>
</tr>
<tr>
<th>Adresse</th>
<td>{{ assooptions.adresse1 }}<br>
{{ assooptions.adresse2 }}</td>
<th>Contact mail</th>
<td>{{ assooptions.contact }}</td>
</tr>
<tr>
<th>Telephone</th>
<td>{{ assooptions.telephone }}</td>
<th>Pseudo d'usage</th>
<td>{{ assooptions.pseudo }}</td>
</tr>
<tr>
<th>Objet utilisateur de l'association</th>
<td>{{ assooptions.utilisateur_asso }}</td>
<th>Description de l'association</th>
<td>{{ assooptions.description | safe }}</td>
</tr>
</table>
<h4>Messages personalisé dans les mails</h4>
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'MailMessageOption' %}">
<i class="fa fa-edit"></i>
Editer
<i class="fa fa-edit"></i> Editer
</a>
<p>
</p>