mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 07:02:26 +00:00
Merge branch 'mail_account' into 'master'
Mail account See merge request federez/re2o!199
This commit is contained in:
commit
90674d4978
15 changed files with 820 additions and 165 deletions
|
@ -495,7 +495,8 @@ class UserSerializer(NamespacedHMSerializer):
|
|||
|
||||
class Meta:
|
||||
model = users.User
|
||||
fields = ('name', 'pseudo', 'email', 'school', 'shell', 'comment',
|
||||
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 = {
|
||||
|
@ -512,7 +513,8 @@ class ClubSerializer(NamespacedHMSerializer):
|
|||
|
||||
class Meta:
|
||||
model = users.Club
|
||||
fields = ('name', 'pseudo', 'email', 'school', 'shell', 'comment',
|
||||
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')
|
||||
|
@ -529,9 +531,10 @@ class AdherentSerializer(NamespacedHMSerializer):
|
|||
|
||||
class Meta:
|
||||
model = users.Adherent
|
||||
fields = ('name', 'surname', 'pseudo', 'email', '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'}
|
||||
}
|
||||
|
@ -593,6 +596,15 @@ class WhitelistSerializer(NamespacedHMSerializer):
|
|||
fields = ('user', 'raison', 'date_start', 'date_end', 'active', 'api_url')
|
||||
|
||||
|
||||
class EMailAddressSerializer(NamespacedHMSerializer):
|
||||
"""Serialize `users.models.EMailAddress` objects.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = users.EMailAddress
|
||||
fields = ('user', 'local_part', 'complete_email_address', 'api_url')
|
||||
|
||||
|
||||
# SERVICE REGEN
|
||||
|
||||
|
||||
|
@ -611,6 +623,21 @@ class ServiceRegenSerializer(NamespacedHMSerializer):
|
|||
}
|
||||
|
||||
|
||||
# LOCAL EMAILS
|
||||
|
||||
|
||||
class LocalEmailUsersSerializer(NamespacedHMSerializer):
|
||||
email_address = EMailAddressSerializer(
|
||||
read_only=True,
|
||||
many=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = users.User
|
||||
fields = ('local_email_enabled', 'local_email_redirect',
|
||||
'email_address')
|
||||
|
||||
|
||||
# DHCP
|
||||
|
||||
|
||||
|
|
|
@ -93,10 +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/emailaddress', views.EMailAddressViewSet)
|
||||
# SERVICE REGEN
|
||||
router.register_viewset(r'services/regen', views.ServiceRegenViewSet, base_name='serviceregen')
|
||||
# DHCP
|
||||
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
|
||||
# LOCAL EMAILS
|
||||
router.register_view(r'localemail/users', views.LocalEmailUsersView),
|
||||
# DNS
|
||||
router.register_view(r'dns/zones', views.DNSZonesView),
|
||||
# MAILING
|
||||
|
|
34
api/views.py
34
api/views.py
|
@ -469,6 +469,21 @@ class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
serializer_class = serializers.WhitelistSerializer
|
||||
|
||||
|
||||
class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
"""Exposes list and details of `users.models.EMailAddress` objects.
|
||||
"""
|
||||
serializer_class = serializers.EMailAddressSerializer
|
||||
queryset = users.EMailAddress.objects.none()
|
||||
|
||||
def get_queryset(self):
|
||||
if preferences.OptionalUser.get_cached_value(
|
||||
'local_email_accounts_enabled'):
|
||||
return (users.EMailAddress.objects
|
||||
.filter(user__local_email_enabled=True))
|
||||
else:
|
||||
return users.EMailAddress.objects.none()
|
||||
|
||||
|
||||
# SERVICE REGEN
|
||||
|
||||
|
||||
|
@ -489,8 +504,26 @@ class ServiceRegenViewSet(viewsets.ModelViewSet):
|
|||
return queryset
|
||||
|
||||
|
||||
# LOCAL EMAILS
|
||||
|
||||
|
||||
class LocalEmailUsersView(generics.ListAPIView):
|
||||
"""Exposes all the aliases of the users that activated the internal address
|
||||
"""
|
||||
serializer_class = serializers.LocalEmailUsersSerializer
|
||||
|
||||
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.
|
||||
|
@ -501,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.
|
||||
|
|
30
preferences/migrations/0046_optionaluser_mail_extension.py
Normal file
30
preferences/migrations/0046_optionaluser_mail_extension.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.7 on 2018-06-26 19:31
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('preferences', '0045_remove_unused_payment_fields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='optionaluser',
|
||||
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_email_address',
|
||||
field=models.IntegerField(default=15, help_text='Maximum number of local email address for a standard user'),
|
||||
),
|
||||
]
|
|
@ -30,6 +30,7 @@ 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 machines.models
|
||||
from re2o.mixins import AclMixin
|
||||
|
@ -83,12 +84,32 @@ class OptionalUser(AclMixin, PreferencesModel):
|
|||
blank=True,
|
||||
null=True
|
||||
)
|
||||
local_email_accounts_enabled = models.BooleanField(
|
||||
default=False,
|
||||
help_text="Enable local email accounts for users"
|
||||
)
|
||||
local_email_domain = models.CharField(
|
||||
max_length = 32,
|
||||
default = "@example.org",
|
||||
help_text="Domain to use for local email accounts",
|
||||
)
|
||||
max_email_address = models.IntegerField(
|
||||
default = 15,
|
||||
help_text = "Maximum number of local email address for a standard user"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
("view_optionaluser", "Peut voir les options de l'user"),
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
"""Clean model:
|
||||
Check the mail_extension
|
||||
"""
|
||||
if self.local_email_domain[0] != "@":
|
||||
raise ValidationError("Mail domain must begin with @")
|
||||
|
||||
|
||||
@receiver(post_save, sender=OptionalUser)
|
||||
def optionaluser_post_save(**kwargs):
|
||||
|
|
314
preferences/templates/preferences/display_preferences.html
Executable file → Normal file
314
preferences/templates/preferences/display_preferences.html
Executable file → Normal file
|
@ -32,194 +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
|
||||
<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>
|
||||
<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 d'alias mail max</th>
|
||||
<td>{{ useroptions.max_email_address }}</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
|
||||
<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>
|
||||
<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>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Mail de bienvenue (Français)</th>
|
||||
<td>{{ mailmessageoptions.welcome_mail_fr | safe }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Mail de bienvenue (Anglais)</th>
|
||||
<td>{{ mailmessageoptions.welcome_mail_en | safe }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Mail de bienvenue (Français)</th>
|
||||
<td>{{ mailmessageoptions.welcome_mail_fr | safe }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Mail de bienvenue (Anglais)</th>
|
||||
<td>{{ mailmessageoptions.welcome_mail_en | safe }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Liste des services et préférences page d'accueil</h2>
|
||||
|
||||
|
||||
<h4>Liste des services et préférences page d'accueil</h4>
|
||||
{% can_create preferences.Service%}
|
||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:add-service' %}"><i class="fa fa-plus"></i> Ajouter un service</a>
|
||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:add-service' %}"><i class="fa fa-plus">
|
||||
</i> Ajouter un service
|
||||
</a>
|
||||
{% acl_end %}
|
||||
<a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-services' %}"><i class="fa fa-trash"></i> Supprimer un ou plusieurs service</a>
|
||||
<a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-services' %}"><i class="fa fa-trash">
|
||||
</i> Supprimer un ou plusieurs service
|
||||
</a>
|
||||
{% include "preferences/aff_service.html" with service_list=service_list %}
|
||||
|
||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'HomeOption' %}">
|
||||
<i class="fa fa-edit"></i>
|
||||
Editer
|
||||
<i class="fa fa-edit"></i> Editer
|
||||
</a>
|
||||
<p>
|
||||
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Url du compte twitter</th>
|
||||
<td>{{ homeoptions.twitter_url }}</td>
|
||||
<th>Nom utilisé pour afficher le compte</th>
|
||||
<td>{{ homeoptions.twitter_account_name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Url du compte facebook</th>
|
||||
<td>{{ homeoptions.facebook_url }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Url du compte twitter</th>
|
||||
<td>{{ homeoptions.twitter_url }}</td>
|
||||
<th>Nom utilisé pour afficher le compte</th>
|
||||
<td>{{ homeoptions.twitter_account_name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Url du compte facebook</th>
|
||||
<td>{{ homeoptions.facebook_url }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
{% endblock %}
|
||||
|
|
|
@ -34,6 +34,7 @@ from reversion.admin import VersionAdmin
|
|||
|
||||
from .models import (
|
||||
User,
|
||||
EMailAddress,
|
||||
ServiceUser,
|
||||
School,
|
||||
ListRight,
|
||||
|
@ -108,6 +109,11 @@ class BanAdmin(VersionAdmin):
|
|||
pass
|
||||
|
||||
|
||||
class EMailAddressAdmin(VersionAdmin):
|
||||
"""Gestion des alias mail"""
|
||||
pass
|
||||
|
||||
|
||||
class WhitelistAdmin(VersionAdmin):
|
||||
"""Gestion des whitelist"""
|
||||
pass
|
||||
|
@ -126,6 +132,8 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
|
|||
'pseudo',
|
||||
'surname',
|
||||
'email',
|
||||
'local_email_redirect',
|
||||
'local_email_enabled',
|
||||
'school',
|
||||
'is_admin',
|
||||
'shell'
|
||||
|
@ -211,6 +219,7 @@ admin.site.register(School, SchoolAdmin)
|
|||
admin.site.register(ListRight, ListRightAdmin)
|
||||
admin.site.register(ListShell, ListShellAdmin)
|
||||
admin.site.register(Ban, BanAdmin)
|
||||
admin.site.register(EMailAddress, EMailAddressAdmin)
|
||||
admin.site.register(Whitelist, WhitelistAdmin)
|
||||
admin.site.register(Request, RequestAdmin)
|
||||
# Now register the new UserAdmin...
|
||||
|
|
|
@ -53,6 +53,7 @@ from .models import (
|
|||
School,
|
||||
ListRight,
|
||||
Whitelist,
|
||||
EMailAddress,
|
||||
ListShell,
|
||||
Ban,
|
||||
Adherent,
|
||||
|
@ -219,7 +220,7 @@ class UserChangeForm(FormRevMixin, forms.ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = Adherent
|
||||
fields = ('pseudo', 'password', 'surname', 'email')
|
||||
fields = ('pseudo', 'password', 'surname')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
|
@ -312,7 +313,6 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
|||
'name',
|
||||
'surname',
|
||||
'pseudo',
|
||||
'email',
|
||||
'school',
|
||||
'comment',
|
||||
'room',
|
||||
|
@ -364,7 +364,6 @@ class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
|||
fields = [
|
||||
'surname',
|
||||
'pseudo',
|
||||
'email',
|
||||
'school',
|
||||
'comment',
|
||||
'room',
|
||||
|
@ -590,3 +589,39 @@ class WhitelistForm(FormRevMixin, ModelForm):
|
|||
model = Whitelist
|
||||
exclude = ['user']
|
||||
widgets = {'date_end':DateTimePicker}
|
||||
|
||||
|
||||
class EMailAddressForm(FormRevMixin, ModelForm):
|
||||
"""Create and edit a local email address"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
super(EMailAddressForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
self.fields['local_part'].label = "Local part of the email"
|
||||
self.fields['local_part'].help_text = "Can't contain @"
|
||||
|
||||
class Meta:
|
||||
model = EMailAddress
|
||||
exclude = ['user']
|
||||
|
||||
|
||||
class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||
"""Edit email-related settings"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||
super(EmailSettingsForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||
self.fields['email'].label = "Contact email address"
|
||||
if 'local_email_redirect' in self.fields:
|
||||
self.fields['local_email_redirect'].label = "Redirect local emails"
|
||||
self.fields['local_email_redirect'].help_text = (
|
||||
"Enable the automated redirection of the local email address "
|
||||
"to the contact email address"
|
||||
)
|
||||
if 'local_email_enabled' in self.fields:
|
||||
self.fields['local_email_enabled'].label = "Use local emails"
|
||||
self.fields['local_email_enabled'].help_text = (
|
||||
"Enable the use of the local email account"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['email', 'local_email_redirect', 'local_email_enabled']
|
||||
|
|
57
users/migrations/0073_auto_20180629_1614.py
Normal file
57
users/migrations/0073_auto_20180629_1614.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.7 on 2018-06-29 14:14
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import re2o.mixins
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
def create_initial_email_address(apps, schema_editor):
|
||||
db_alias = schema_editor.connection.alias
|
||||
User = apps.get_model("users", "User")
|
||||
EMailAddress = apps.get_model("users", "EMailAddress")
|
||||
users = User.objects.using(db_alias).all()
|
||||
for user in users:
|
||||
EMailAddress.objects.using(db_alias).create(
|
||||
local_part=user.pseudo,
|
||||
user=user
|
||||
)
|
||||
|
||||
def delete_all_email_address(apps, schema_editor):
|
||||
db_alias = schema_editor.connection.alias
|
||||
EMailAddress = apps.get_model("users", "EMailAddress")
|
||||
EMailAddress.objects.using(db_alias).delete()
|
||||
|
||||
dependencies = [
|
||||
('users', '0072_auto_20180426_2021'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EMailAddress',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('local_part', models.CharField(help_text="Local part of the email address", max_length=128, unique=True)),
|
||||
('user', models.ForeignKey(help_text='User of the local email', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model),
|
||||
options={'permissions': (('view_emailaddress', 'Can see a local email account object'),), 'verbose_name': 'Local email account', 'verbose_name_plural': 'Local email accounts'},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='local_email_enabled',
|
||||
field=models.BooleanField(default=False, help_text="Wether or not to enable the local email account."),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='local_email_redirect',
|
||||
field=models.BooleanField(default=False, help_text='Whether or not to redirect the local email messages to the main email.'),
|
||||
),
|
||||
migrations.RunPython(create_initial_email_address,
|
||||
delete_all_email_address),
|
||||
]
|
||||
|
176
users/models.py
Normal file → Executable file
176
users/models.py
Normal file → Executable file
|
@ -148,7 +148,7 @@ class UserManager(BaseUserManager):
|
|||
pseudo=pseudo,
|
||||
surname=surname,
|
||||
name=surname,
|
||||
email=self.normalize_email(email),
|
||||
email=self.normalize_email(mail),
|
||||
)
|
||||
|
||||
user.set_password(password)
|
||||
|
@ -195,6 +195,14 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
|||
validators=[linux_user_validator]
|
||||
)
|
||||
email = models.EmailField()
|
||||
local_email_redirect = models.BooleanField(
|
||||
default=False,
|
||||
help_text="Whether or not to redirect the local email messages to the main email."
|
||||
)
|
||||
local_email_enabled = models.BooleanField(
|
||||
default=False,
|
||||
help_text="Wether or not to enable the local email account."
|
||||
)
|
||||
school = models.ForeignKey(
|
||||
'School',
|
||||
on_delete=models.PROTECT,
|
||||
|
@ -674,6 +682,13 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
|||
self.pwd_ntlm = hashNT(password)
|
||||
return
|
||||
|
||||
@cached_property
|
||||
def email_address(self):
|
||||
if (OptionalUser.get_cached_value('local_email_accounts_enabled')
|
||||
and self.local_email_enabled):
|
||||
return self.emailaddress_set.all()
|
||||
return EMailAddress.objects.none()
|
||||
|
||||
def get_next_domain_name(self):
|
||||
"""Look for an available name for a new interface for
|
||||
this user by trying "pseudo0", "pseudo1", "pseudo2", ...
|
||||
|
@ -792,6 +807,32 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
|||
"Droit requis pour changer le shell"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def can_change_local_email_redirect(user_request, *_args, **_kwargs):
|
||||
""" Check if a user can change local_email_redirect.
|
||||
|
||||
:param user_request: The user who request
|
||||
:returns: a message and a boolean which is True if the user has
|
||||
the right to change a redirection
|
||||
"""
|
||||
return (
|
||||
OptionalUser.get_cached_value('local_email_accounts_enabled'),
|
||||
"La gestion des comptes mails doit être activée"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def can_change_local_email_enabled(user_request, *_args, **_kwargs):
|
||||
""" Check if a user can change internal address .
|
||||
|
||||
:param user_request: The user who request
|
||||
:returns: a message and a boolean which is True if the user has
|
||||
the right to change internal address
|
||||
"""
|
||||
return (
|
||||
OptionalUser.get_cached_value('local_email_accounts_enabled'),
|
||||
"La gestion des comptes mails doit être activée"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def can_change_force(user_request, *_args, **_kwargs):
|
||||
""" Check if a user can change a force
|
||||
|
@ -886,9 +927,19 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
|||
'shell': self.can_change_shell,
|
||||
'force': self.can_change_force,
|
||||
'selfpasswd': self.check_selfpasswd,
|
||||
'local_email_redirect': self.can_change_local_email_redirect,
|
||||
'local_email_enabled' : self.can_change_local_email_enabled,
|
||||
}
|
||||
self.__original_state = self.state
|
||||
|
||||
def clean(self, *args, **kwargs):
|
||||
"""Check if this pseudo is already used by any mailalias.
|
||||
Better than raising an error in post-save and catching it"""
|
||||
if (EMailAddress.objects
|
||||
.filter(local_part=self.pseudo)
|
||||
.exclude(user=self)):
|
||||
raise ValidationError("This pseudo is already in use.")
|
||||
|
||||
def __str__(self):
|
||||
return self.pseudo
|
||||
|
||||
|
@ -1011,9 +1062,11 @@ class Club(User):
|
|||
@receiver(post_save, sender=User)
|
||||
def user_post_save(**kwargs):
|
||||
""" Synchronisation post_save : envoie le mail de bienvenue si creation
|
||||
Synchronise le pseudo, en créant un alias mail correspondant
|
||||
Synchronise le ldap"""
|
||||
is_created = kwargs['created']
|
||||
user = kwargs['instance']
|
||||
EMailAddress.objects.get_or_create(local_part=user.pseudo, user=user)
|
||||
if is_created:
|
||||
user.notif_inscription()
|
||||
user.state_sync()
|
||||
|
@ -1593,3 +1646,124 @@ class LdapServiceUserGroup(ldapdb.models.Model):
|
|||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class EMailAddress(RevMixin, AclMixin, models.Model):
|
||||
"""Defines a local email account for a user
|
||||
"""
|
||||
user = models.ForeignKey(
|
||||
User,
|
||||
on_delete=models.CASCADE,
|
||||
help_text="User of the local email",
|
||||
)
|
||||
local_part = models.CharField(
|
||||
unique=True,
|
||||
max_length=128,
|
||||
help_text="Local part of the email address"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
("view_emailaddress", "Can see a local email account object"),
|
||||
)
|
||||
verbose_name = "Local email account"
|
||||
verbose_name_plural = "Local email accounts"
|
||||
|
||||
def __str__(self):
|
||||
return self.local_part + OptionalUser.get_cached_value('local_email_domain')
|
||||
|
||||
@cached_property
|
||||
def complete_email_address(self):
|
||||
return self.local_part + OptionalUser.get_cached_value('local_email_domain')
|
||||
|
||||
@staticmethod
|
||||
def can_create(user_request, userid, *_args, **_kwargs):
|
||||
"""Check if a user can create a `EMailAddress` object.
|
||||
|
||||
Args:
|
||||
user_request: The user who wants to create the object.
|
||||
userid: The id of the user to whom the account is to be created
|
||||
|
||||
Returns:
|
||||
a message and a boolean which is True if the user can create
|
||||
a local email account.
|
||||
"""
|
||||
if user_request.has_perm('users.add_emailaddress'):
|
||||
return True, None
|
||||
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
|
||||
return False, "The local email accounts are not enabled."
|
||||
if int(user_request.id) != int(userid):
|
||||
return False, "You don't have the right to add a local email account to another user."
|
||||
elif user_request.email_address.count() >= OptionalUser.get_cached_value('max_email_address'):
|
||||
return False, "You have reached the limit of {} local email account.".format(
|
||||
OptionalUser.get_cached_value('max_email_address')
|
||||
)
|
||||
return True, None
|
||||
|
||||
def can_view(self, user_request, *_args, **_kwargs):
|
||||
"""Check if a user can view the local email account
|
||||
|
||||
Args:
|
||||
user_request: The user who wants to view the object.
|
||||
|
||||
Returns:
|
||||
a message and a boolean which is True if the user can see
|
||||
the local email account.
|
||||
"""
|
||||
if user_request.has_perm('users.view_emailaddress'):
|
||||
return True, None
|
||||
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
|
||||
return False, "The local email accounts are not enabled."
|
||||
if user_request == self.user:
|
||||
return True, None
|
||||
return False, "You don't have the right to edit someone else's local email account."
|
||||
|
||||
def can_delete(self, user_request, *_args, **_kwargs):
|
||||
"""Check if a user can delete the alias
|
||||
|
||||
Args:
|
||||
user_request: The user who wants to delete the object.
|
||||
|
||||
Returns:
|
||||
a message and a boolean which is True if the user can delete
|
||||
the local email account.
|
||||
"""
|
||||
if self.local_part == self.user.pseudo:
|
||||
return False, ("You cannot delete a local email account whose "
|
||||
"local part is the same as the username.")
|
||||
if user_request.has_perm('users.delete_emailaddress'):
|
||||
return True, None
|
||||
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
|
||||
return False, "The local email accounts are not enabled."
|
||||
if user_request == self.user:
|
||||
return True, None
|
||||
return False, ("You don't have the right to delete someone else's "
|
||||
"local email account")
|
||||
|
||||
def can_edit(self, user_request, *_args, **_kwargs):
|
||||
"""Check if a user can edit the alias
|
||||
|
||||
Args:
|
||||
user_request: The user who wants to edit the object.
|
||||
|
||||
Returns:
|
||||
a message and a boolean which is True if the user can edit
|
||||
the local email account.
|
||||
"""
|
||||
if self.local_part == self.user.pseudo:
|
||||
return False, ("You cannot edit a local email account whose "
|
||||
"local part is the same as the username.")
|
||||
if user_request.has_perm('users.change_emailaddress'):
|
||||
return True, None
|
||||
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
|
||||
return False, "The local email accounts are not enabled."
|
||||
if user_request == self.user:
|
||||
return True, None
|
||||
return False, ("You don't have the right to edit someone else's "
|
||||
"local email account")
|
||||
|
||||
def clean(self, *args, **kwargs):
|
||||
if "@" in self.local_part:
|
||||
raise ValidationError("The local part cannot contain a @")
|
||||
super(EMailAddress, self).clean(*args, **kwargs)
|
||||
|
||||
|
|
56
users/templates/users/aff_emailaddress.html
Normal file
56
users/templates/users/aff_emailaddress.html
Normal file
|
@ -0,0 +1,56 @@
|
|||
{% 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 © 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.
|
||||
{% endcomment %}
|
||||
|
||||
{% load acl %}
|
||||
{% load logs_extra %}
|
||||
|
||||
{% if emailaddress_list.paginator %}
|
||||
{% include "pagination.html" with list=emailaddress_list %}
|
||||
{% endif %}
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Email address</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for emailaddress in emailaddress_list %}
|
||||
<td>{{ emailaddress.complete_email_address }}</td>
|
||||
<td class="text-right">
|
||||
{% can_delete emailaddress %}
|
||||
{% include 'buttons/suppr.html' with href='users:del-emailaddress' id=emailaddress.id %}
|
||||
{% acl_end %}
|
||||
{% can_edit emailaddress %}
|
||||
{% include 'buttons/edit.html' with href='users:edit-emailaddress' id=emailaddress.id %}
|
||||
{% acl_end %}
|
||||
{% history_button emailaddress %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% if emailaddress_list.paginator %}
|
||||
{% include "pagination.html" with list=emailaddress_list %}
|
||||
{% endif %}
|
34
users/templates/users/index_emailaddress.html
Normal file
34
users/templates/users/index_emailaddress.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
{% extends "users/sidebar.html" %}
|
||||
{% 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 © 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.
|
||||
{% endcomment %}
|
||||
|
||||
{% load bootstrap3 %}
|
||||
|
||||
{% block title %}Local email accounts{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Local email accounts</h2>
|
||||
{% include "users/aff_emailaddress.html" with emailaddress_list=emailaddress_list %}
|
||||
{% endblock %}
|
||||
|
|
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
{% load bootstrap3 %}
|
||||
{% load acl %}
|
||||
{% load logs_extra %}
|
||||
{% load design %}
|
||||
|
||||
{% block title %}Profil{% endblock %}
|
||||
|
||||
|
@ -406,8 +407,58 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading clearfix" data-parent="#accordion" data-toggle="collapse" data-target="#collapse7">
|
||||
<h3 class="panel-title pull-left">
|
||||
<i class="fa fa-envelope"></i> Email settings
|
||||
</h3>
|
||||
</div>
|
||||
<div id="collapse7" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
{% can_edit users %}
|
||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-email-settings' users.id %}">
|
||||
<i class="fa fa-pencil-alt"></i> Edit email settings
|
||||
</a>
|
||||
{% acl_end %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if local_email_accounts_enabled %}
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th colspan="2">Contact email address</th>
|
||||
<td colspan="2">{{ users.email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Enable the local email account</th>
|
||||
<td>{{ users.local_email_enabled | tick }}</td>
|
||||
<th>Enable the local email redirection</th>
|
||||
<td>{{ users.local_email_redirect | tick }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% if users.local_email_enabled %}
|
||||
{% can_create EMailAddress users.id %}
|
||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:add-emailaddress' users.id %}">
|
||||
<i class="fa fa-plus-square"></i> Add an email address
|
||||
</a>
|
||||
{% acl_end %}
|
||||
{% if emailaddress_list %}
|
||||
{% include "users/aff_emailaddress.html" with emailaddress_list=emailaddress_list %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Contact email address</th>
|
||||
<td>{{ users.email }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
{% endblock %}
|
||||
|
|
|
@ -64,6 +64,18 @@ urlpatterns = [
|
|||
url(r'^del_whitelist/(?P<whitelistid>[0-9]+)$',
|
||||
views.del_whitelist,
|
||||
name='del-whitelist'),
|
||||
url(r'^add_emailaddress/(?P<userid>[0-9]+)$',
|
||||
views.add_emailaddress,
|
||||
name='add-emailaddress'),
|
||||
url(r'^edit_emailaddress/(?P<emailaddressid>[0-9]+)$',
|
||||
views.edit_emailaddress,
|
||||
name='edit-emailaddress'),
|
||||
url(r'^del_emailaddress/(?P<emailaddressid>[0-9]+)$',
|
||||
views.del_emailaddress,
|
||||
name='del-emailaddress'),
|
||||
url(r'^edit_email_settings/(?P<userid>[0-9]+)$',
|
||||
views.edit_email_settings,
|
||||
name='edit-email-settings'),
|
||||
url(r'^add_school/$', views.add_school, name='add-school'),
|
||||
url(r'^edit_school/(?P<schoolid>[0-9]+)$',
|
||||
views.edit_school,
|
||||
|
|
104
users/views.py
104
users/views.py
|
@ -81,10 +81,13 @@ from .models import (
|
|||
Adherent,
|
||||
Club,
|
||||
ListShell,
|
||||
EMailAddress,
|
||||
)
|
||||
from .forms import (
|
||||
BanForm,
|
||||
WhitelistForm,
|
||||
EMailAddressForm,
|
||||
EmailSettingsForm,
|
||||
DelSchoolForm,
|
||||
DelListRightForm,
|
||||
NewListRightForm,
|
||||
|
@ -492,6 +495,101 @@ def del_whitelist(request, whitelist, **_kwargs):
|
|||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@can_create(EMailAddress)
|
||||
@can_edit(User)
|
||||
def add_emailaddress(request, user, userid):
|
||||
""" Create a new local email account"""
|
||||
emailaddress_instance = EMailAddress(user=user)
|
||||
emailaddress = EMailAddressForm(
|
||||
request.POST or None,
|
||||
instance=emailaddress_instance
|
||||
)
|
||||
if emailaddress.is_valid():
|
||||
emailaddress.save()
|
||||
messages.success(request, "Local email account created")
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': str(userid)}
|
||||
))
|
||||
return form(
|
||||
{'userform': emailaddress,
|
||||
'showCGU': False,
|
||||
'action_name': 'Add a local email account'},
|
||||
'users/user.html',
|
||||
request
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@can_edit(EMailAddress)
|
||||
def edit_emailaddress(request, emailaddress_instance, **_kwargs):
|
||||
""" Edit a local email account"""
|
||||
emailaddress = EMailAddressForm(
|
||||
request.POST or None,
|
||||
instance=emailaddress_instance
|
||||
)
|
||||
if emailaddress.is_valid():
|
||||
if emailaddress.changed_data:
|
||||
emailaddress.save()
|
||||
messages.success(request, "Local email account modified")
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': str(emailaddress_instance.user.id)}
|
||||
))
|
||||
return form(
|
||||
{'userform': emailaddress,
|
||||
'showCGU': False,
|
||||
'action_name': 'Edit a local email account'},
|
||||
'users/user.html',
|
||||
request
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@can_delete(EMailAddress)
|
||||
def del_emailaddress(request, emailaddress, **_kwargs):
|
||||
"""Delete a local email account"""
|
||||
if request.method == "POST":
|
||||
emailaddress.delete()
|
||||
messages.success(request, "Local email account deleted")
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': str(emailaddress.user.id)}
|
||||
))
|
||||
return form(
|
||||
{'objet': emailaddress, 'objet_name': 'emailaddress'},
|
||||
'users/delete.html',
|
||||
request
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@can_edit(User)
|
||||
def edit_email_settings(request, user_instance, **_kwargs):
|
||||
"""Edit the email settings of a user"""
|
||||
email_settings = EmailSettingsForm(
|
||||
request.POST or None,
|
||||
instance=user_instance,
|
||||
user=request.user
|
||||
)
|
||||
if email_settings.is_valid():
|
||||
if email_settings.changed_data:
|
||||
email_settings.save()
|
||||
messages.success(request, "Email settings updated")
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': str(user_instance.id)}
|
||||
))
|
||||
return form(
|
||||
{'userform': email_settings,
|
||||
'showCGU': False,
|
||||
'action_name': 'Edit the email settings'},
|
||||
'users/user.html',
|
||||
request
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@can_create(School)
|
||||
def add_school(request):
|
||||
|
@ -914,7 +1012,11 @@ def profil(request, users, **_kwargs):
|
|||
'white_list': whitelists,
|
||||
'user_solde': user_solde,
|
||||
'solde_activated': Paiement.objects.filter(is_balance=True).exists(),
|
||||
'asso_name': AssoOption.objects.first().name
|
||||
'asso_name': AssoOption.objects.first().name,
|
||||
'emailaddress_list': users.email_address,
|
||||
'local_email_accounts_enabled': (
|
||||
OptionalUser.objects.first().local_email_accounts_enabled
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue