From 43fb83ec121323b651393b67a4357b5191a354bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Kervella?= Date: Mon, 30 Jul 2018 15:00:41 +0000 Subject: [PATCH] Cleanup for local email accounts --- api/serializers.py | 46 ++- api/urls.py | 6 +- api/views.py | 34 +- .../0035_optionaluser_mail_extension.py | 20 - .../0036_optionaluser_mail_accounts.py | 20 - .../0037_optionaluser_max_mail_alias.py | 20 - .../migrations/0046_merge_20180723_1413.py | 16 - .../0046_optionaluser_mail_extension.py | 30 ++ preferences/models.py | 21 +- .../preferences/display_preferences.html | 342 +++++++++--------- preferences/urls.py | 1 + re2o/templatetags/acl.py | 1 + users/admin.py | 14 +- users/forms.py | 42 ++- users/migrations/0073_auto_20180629_1614.py | 42 ++- users/migrations/0074_auto_20180629_1717.py | 42 --- users/models.py | 219 ++++++----- ...alias.html => aff_localemailaccounts.html} | 40 +- ...lias.html => index_localemailaccount.html} | 9 +- users/templates/users/profil.html | 94 +++-- users/urls.py | 16 +- users/views.py | 111 +++--- 22 files changed, 587 insertions(+), 599 deletions(-) mode change 100755 => 100644 api/serializers.py mode change 100755 => 100644 api/urls.py mode change 100755 => 100644 api/views.py delete mode 100644 preferences/migrations/0035_optionaluser_mail_extension.py delete mode 100644 preferences/migrations/0036_optionaluser_mail_accounts.py delete mode 100644 preferences/migrations/0037_optionaluser_max_mail_alias.py delete mode 100644 preferences/migrations/0046_merge_20180723_1413.py create mode 100644 preferences/migrations/0046_optionaluser_mail_extension.py mode change 100755 => 100644 preferences/templates/preferences/display_preferences.html delete mode 100644 users/migrations/0074_auto_20180629_1717.py rename users/templates/users/{aff_mailalias.html => aff_localemailaccounts.html} (60%) rename users/templates/users/{index_alias.html => index_localemailaccount.html} (85%) diff --git a/api/serializers.py b/api/serializers.py old mode 100755 new mode 100644 index c9825f32..d07cb9fe --- a/api/serializers.py +++ b/api/serializers.py @@ -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 diff --git a/api/urls.py b/api/urls.py old mode 100755 new mode 100644 index 049d99bf..88211c4b --- a/api/urls.py +++ b/api/urls.py @@ -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 diff --git a/api/views.py b/api/views.py old mode 100755 new mode 100644 index 4d5cae27..04c7a461 --- a/api/views.py +++ b/api/views.py @@ -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. diff --git a/preferences/migrations/0035_optionaluser_mail_extension.py b/preferences/migrations/0035_optionaluser_mail_extension.py deleted file mode 100644 index dd26f433..00000000 --- a/preferences/migrations/0035_optionaluser_mail_extension.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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', '0034_auto_20180416_1120'), - ] - - 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), - ), - ] diff --git a/preferences/migrations/0036_optionaluser_mail_accounts.py b/preferences/migrations/0036_optionaluser_mail_accounts.py deleted file mode 100644 index db604287..00000000 --- a/preferences/migrations/0036_optionaluser_mail_accounts.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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'), - ), - ] diff --git a/preferences/migrations/0037_optionaluser_max_mail_alias.py b/preferences/migrations/0037_optionaluser_max_mail_alias.py deleted file mode 100644 index f5198177..00000000 --- a/preferences/migrations/0037_optionaluser_max_mail_alias.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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"), - ), - ] diff --git a/preferences/migrations/0046_merge_20180723_1413.py b/preferences/migrations/0046_merge_20180723_1413.py deleted file mode 100644 index b3dfaca6..00000000 --- a/preferences/migrations/0046_merge_20180723_1413.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- 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 = [ - ] diff --git a/preferences/migrations/0046_optionaluser_mail_extension.py b/preferences/migrations/0046_optionaluser_mail_extension.py new file mode 100644 index 00000000..5fc6c5e0 --- /dev/null +++ b/preferences/migrations/0046_optionaluser_mail_extension.py @@ -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_local_email_accounts', + field=models.IntegerField(default=15, help_text='Maximum number of local email accounts for a standard user'), + ), + ] diff --git a/preferences/models.py b/preferences/models.py index aa1a662b..5f13bc4b 100644 --- a/preferences/models.py +++ b/preferences/models.py @@ -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): diff --git a/preferences/templates/preferences/display_preferences.html b/preferences/templates/preferences/display_preferences.html old mode 100755 new mode 100644 index 7e503021..c6f11734 --- a/preferences/templates/preferences/display_preferences.html +++ b/preferences/templates/preferences/display_preferences.html @@ -32,206 +32,204 @@ with this program; if not, write to the Free Software Foundation, Inc., {% block content %}

Préférences utilisateur

- - Editer - -

-

-
Généralités
- - - - - - - - - - - - - - - - - - - -
{% if useroptions.mail_accounts %}Comptes mails{% else %}Comptes mails{% endif%}
-
Téléphone obligatoirement requis{{ useroptions.is_tel_mandatory|tick }}Auto inscription{{ useroptions.self_adhesion|tick }}
Champ gpg fingerprint{{ useroptions.gpg_fingerprint|tick }}Shell par défaut des utilisateurs{{ useroptions.shell_default }}
Creations d'adhérents par tous{{ useroptions.all_can_create_adherent|tick }}Creations de clubs par tous{{ useroptions.all_can_create_club|tick }}
- - - - - - - - - -
Gestion des comptes mails{{ useroptions.mail_accounts }}Extension mail interne{{ useroptions.mail_extension }}
Nombre d'alias maximum{{ useroption.max_mail_alias }} -
+ Editer + -

Préférences machines

- - - Editer - -

-

- - - - - - - - - - - - - - - - - +
Généralités
+
Mot de passe par machine{{ machineoptions.password_machine|tick }}Machines/interfaces autorisées par utilisateurs{{ machineoptions.max_lambdauser_interfaces }}
Alias dns autorisé par utilisateur{{ machineoptions.max_lambdauser_aliases }}Support de l'ipv6{{ machineoptions.ipv6_mode }}
Creation de machines{{ machineoptions.create_machine|tick }}
+ + + + + + + + + + + + + + + + + +
Téléphone obligatoirement requis{{ useroptions.is_tel_mandatory|tick }}Auto inscription{{ useroptions.self_adhesion|tick }}
Champ gpg fingerprint{{ useroptions.gpg_fingerprint|tick }}Shell par défaut des utilisateurs{{ useroptions.shell_default }}
Creations d'adhérents par tous{{ useroptions.all_can_create_adherent|tick }}Creations de clubs par tous{{ useroptions.all_can_create_club|tick }}
+ +
Comptes mails
+ + + + + + + + + + + +
Gestion des comptes mails{{ useroptions.local_email_accounts_enabled | tick }}Extension mail interne{{ useroptions.local_email_domain }}
Nombre de comptes maximum{{ useroptions.max_local_email_accounts }}
+ + +

Préférences machines

+ + Editer + + + + + + + + + + + + + + + + + + +
Mot de passe par machine{{ machineoptions.password_machine|tick }}Machines/interfaces autorisées par utilisateurs{{ machineoptions.max_lambdauser_interfaces }}
Alias dns autorisé par utilisateur{{ machineoptions.max_lambdauser_aliases }}Support de l'ipv6{{ machineoptions.ipv6_mode }}
Creation de machines{{ machineoptions.create_machine|tick }}
+ +

Préférences topologie

- - Editer + Editer -

-

- - - - - - - - - - - - + + + + + + + + + + + +
Politique générale de placement de vlan{{ topologieoptions.radius_general_policy }} 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"
Vlan où placer les machines après acceptation RADIUS{{ topologieoptions.vlan_decision_ok }}Vlan où placer les machines après rejet RADIUS{{ topologieoptions.vlan_decision_nok }}
Politique générale de placement de vlan{{ topologieoptions.radius_general_policy }} + 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" +
Vlan où placer les machines après acceptation RADIUS{{ topologieoptions.vlan_decision_ok }}Vlan où placer les machines après rejet RADIUS{{ topologieoptions.vlan_decision_nok }}
+ +

Préférences generales

- - Editer + Editer -

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + +
Nom du site web{{ generaloptions.site_name }}Adresse mail d'expedition automatique{{ generaloptions.email_from }}
Affichage de résultats dans le champ de recherche{{ generaloptions.search_display_page }}Nombre d'items affichés en liste (taille normale){{ generaloptions.pagination_number }}
Nombre d'items affichés en liste (taille élevée){{ generaloptions.pagination_large_number }}Temps avant expiration du lien de reinitialisation de mot de passe (en heures){{ generaloptions.req_expire_hrs }}
Message global affiché sur le site{{ generaloptions.general_message }}Résumé des CGU{{ generaloptions.GTU_sum_up }}
CGU{{generaloptions.GTU}} -
Nom du site web{{ generaloptions.site_name }}Adresse mail d'expedition automatique{{ generaloptions.email_from }}
Affichage de résultats dans le champ de recherche{{ generaloptions.search_display_page }}Nombre d'items affichés en liste (taille normale){{ generaloptions.pagination_number }}
Nombre d'items affichés en liste (taille élevée){{ generaloptions.pagination_large_number }}Temps avant expiration du lien de reinitialisation de mot de passe (en heures){{ generaloptions.req_expire_hrs }}
Message global affiché sur le site{{ generaloptions.general_message }}Résumé des CGU{{ generaloptions.GTU_sum_up }}
CGU{{generaloptions.GTU}} +
+ +

Données de l'association

- - Editer + Editer -

-

- - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + +
Nom{{ assooptions.name }}SIRET{{ assooptions.siret }}
Adresse{{ assooptions.adresse1 }}
- {{ assooptions.adresse2 }}
Contact mail{{ assooptions.contact }}
Telephone{{ assooptions.telephone }}Pseudo d'usage{{ assooptions.pseudo }}
Objet utilisateur de l'association{{ assooptions.utilisateur_asso }}Description de l'association{{ assooptions.description | safe }}
Nom{{ assooptions.name }}SIRET{{ assooptions.siret }}
Adresse{{ assooptions.adresse1 }}
+ {{ assooptions.adresse2 }}
Contact mail{{ assooptions.contact }}
Telephone{{ assooptions.telephone }}Pseudo d'usage{{ assooptions.pseudo }}
Objet utilisateur de l'association{{ assooptions.utilisateur_asso }}Description de l'association{{ assooptions.description | safe }}
+ +

Messages personalisé dans les mails

- - Editer + Editer -

-

- - - - - - - - + + + + + + + +
Mail de bienvenue (Français){{ mailmessageoptions.welcome_mail_fr | safe }}
Mail de bienvenue (Anglais){{ mailmessageoptions.welcome_mail_en | safe }}
Mail de bienvenue (Français){{ mailmessageoptions.welcome_mail_fr | safe }}
Mail de bienvenue (Anglais){{ mailmessageoptions.welcome_mail_en | safe }}
-

Liste des services et préférences page d'accueil

+ + +

Liste des services et préférences page d'accueil

{% can_create preferences.Service%} - Ajouter un service + + Ajouter un service + {% acl_end %} - Supprimer un ou plusieurs service + + Supprimer un ou plusieurs service + {% include "preferences/aff_service.html" with service_list=service_list %} - - Editer + Editer -

- - - - - - - - - - - + + + + + + + + + +
Url du compte twitter{{ homeoptions.twitter_url }}Nom utilisé pour afficher le compte{{ homeoptions.twitter_account_name }}
Url du compte facebook{{ homeoptions.facebook_url }}
Url du compte twitter{{ homeoptions.twitter_url }}Nom utilisé pour afficher le compte{{ homeoptions.twitter_account_name }}
Url du compte facebook{{ homeoptions.facebook_url }}
-
-
-
{% endblock %} diff --git a/preferences/urls.py b/preferences/urls.py index c94d0758..ec35cc41 100644 --- a/preferences/urls.py +++ b/preferences/urls.py @@ -29,6 +29,7 @@ from django.conf.urls import url from . import views + urlpatterns = [ url( r'^edit_options/(?P

OptionalUser)$', diff --git a/re2o/templatetags/acl.py b/re2o/templatetags/acl.py index 9a439f88..fe13c5ac 100644 --- a/re2o/templatetags/acl.py +++ b/re2o/templatetags/acl.py @@ -79,6 +79,7 @@ from django.contrib.contenttypes.models import ContentType register = template.Library() + def get_model(model_name): """Retrieve the model object from its name""" splitted = model_name.split('.') diff --git a/users/admin.py b/users/admin.py index ee71713c..bc1670a7 100644 --- a/users/admin.py +++ b/users/admin.py @@ -34,7 +34,7 @@ from reversion.admin import VersionAdmin from .models import ( User, - MailAlias, + LocalEmailAccount, ServiceUser, School, ListRight, @@ -109,7 +109,7 @@ class BanAdmin(VersionAdmin): pass -class MailAliasAdmin(VersionAdmin): +class LocalEmailAccountAdmin(VersionAdmin): """Gestion des alias mail""" pass @@ -131,7 +131,9 @@ class UserAdmin(VersionAdmin, BaseUserAdmin): list_display = ( 'pseudo', 'surname', - 'external_mail', + 'email', + 'local_email_redirect', + 'local_email_enabled', 'school', 'is_admin', 'shell' @@ -145,7 +147,7 @@ class UserAdmin(VersionAdmin, BaseUserAdmin): 'Personal info', { 'fields': - ('surname', 'external_mail', 'school', 'shell', 'uid_number') + ('surname', 'email', 'school', 'shell', 'uid_number') } ), ('Permissions', {'fields': ('is_admin', )}), @@ -160,7 +162,7 @@ class UserAdmin(VersionAdmin, BaseUserAdmin): 'fields': ( 'pseudo', 'surname', - 'external_mail', + 'email', 'school', 'is_admin', 'password1', @@ -217,7 +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(MailAlias, MailAliasAdmin) +admin.site.register(LocalEmailAccount, LocalEmailAccountAdmin) admin.site.register(Whitelist, WhitelistAdmin) admin.site.register(Request, RequestAdmin) # Now register the new UserAdmin... diff --git a/users/forms.py b/users/forms.py index 14a630bd..7b17a5ec 100644 --- a/users/forms.py +++ b/users/forms.py @@ -53,7 +53,7 @@ from .models import ( School, ListRight, Whitelist, - MailAlias, + LocalEmailAccount, ListShell, Ban, Adherent, @@ -140,7 +140,7 @@ class UserCreationForm(FormRevMixin, forms.ModelForm): class Meta: model = Adherent - fields = ('pseudo', 'surname') + fields = ('pseudo', 'surname', 'email') def clean_password2(self): """Verifie que password1 et 2 sont identiques""" @@ -306,6 +306,7 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): self.fields['room'].label = 'Chambre' self.fields['room'].empty_label = "Pas de chambre" self.fields['school'].empty_label = "Séléctionner un établissement" + class Meta: model = Adherent fields = [ @@ -590,28 +591,37 @@ class WhitelistForm(FormRevMixin, ModelForm): widgets = {'date_end':DateTimePicker} -class MailAliasForm(FormRevMixin, ModelForm): - """Create and edit a mailalias""" +class LocalEmailAccountForm(FormRevMixin, ModelForm): + """Create and edit a local email account""" def __init__(self, *args, **kwargs): prefix = kwargs.pop('prefix', self.Meta.model.__name__) - super(MailAliasForm, self).__init__(*args, prefix=prefix, **kwargs) - self.fields['valeur'].label = "Prefix of mailalias. Can't contain @" + super(LocalEmailAccountForm, 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 = MailAlias + model = LocalEmailAccount exclude = ['user'] -class MailForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): - """Edit mail settings""" + +class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): + """Edit email-related settings""" def __init__(self, *args, **kwargs): prefix = kwargs.pop('prefix', self.Meta.model.__name__) - super(MailForm, self).__init__(*args, prefix=prefix, **kwargs) - self.fields['external_mail'].label = 'External mail address' - if 'redirection' in self.fields: - self.fields['redirection'].label = 'Enable redirect to external address' - if 'internal_address' in self.fields: - self.fields['internal_address'].label = 'Internal mail address' + 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 = ['external_mail', 'redirection', 'internal_address'] + fields = ['email', 'local_email_redirect', 'local_email_enabled'] diff --git a/users/migrations/0073_auto_20180629_1614.py b/users/migrations/0073_auto_20180629_1614.py index 681cb722..6b976f88 100644 --- a/users/migrations/0073_auto_20180629_1614.py +++ b/users/migrations/0073_auto_20180629_1614.py @@ -10,37 +10,49 @@ import re2o.mixins class Migration(migrations.Migration): + def create_initial_local_email_account(apps, schema_editor): + db_alias = schema_editor.connection.alias + User = apps.get_model("users", "User") + LocalEmailAccount = apps.get_model("users", "LocalEmailAccount") + users = User.objects.using(db_alias).all() + for user in users: + LocalEmailAccount.objects.using(db_alias).create( + local_part=user.pseudo, + user=user + ) + + def delete_all_local_email_accounts(apps, schema_editor): + db_alias = schema_editor.connection.alias + LocalEmailAccount = apps.get_model("users", "LocalEmailAccount") + LocalEmailAccount.objects.using(db_alias).delete() + dependencies = [ ('users', '0072_auto_20180426_2021'), ] operations = [ migrations.CreateModel( - name='MailAlias', + name='LocalEmailAccount', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('valeur', models.CharField(help_text="username de l'adresse mail", max_length=64, unique=True)), + ('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), - ), - migrations.RenameField( - model_name='user', - old_name='email', - new_name='external_mail', + options={'permissions': (('view_localemailaccount', 'Can see a local email account object'),), 'verbose_name': 'Local email account', 'verbose_name_plural': 'Local email accounts'}, ), migrations.AddField( model_name='user', - name='internal_address', - field=models.BooleanField(default=False, help_text="Activer ou non l'utilisation de l'adresse mail interne"), + 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='redirection', - field=models.BooleanField(default=False, help_text='Activer ou non la redirection du mail interne vers le mail externe'), + 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.AddField( - model_name='mailalias', - name='user', - field=models.ForeignKey(blank=True, help_text='Utilisateur associé', null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + migrations.RunPython(create_initial_local_email_account, + delete_all_local_email_accounts), ), ] + diff --git a/users/migrations/0074_auto_20180629_1717.py b/users/migrations/0074_auto_20180629_1717.py deleted file mode 100644 index 4700e34c..00000000 --- a/users/migrations/0074_auto_20180629_1717.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2018-06-29 15:17 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0073_auto_20180629_1614'), - ] - - def transfer_pseudo(apps, schema_editor): - db_alias = schema_editor.connection.alias - users = apps.get_model("users", "User") - mailalias = apps.get_model("users", "MailAlias") - users_list = users.objects.using(db_alias).all() - for user in users_list: - mailalias.objects.using(db_alias).create(valeur=user.pseudo, user=user) - - def untransfer_pseudo(apps, schema_editor): - db_alias = schema_editor.connection.alias - mailalias = apps.get_model("users", "MailAlias") - mailalias.objects.using(db_alias).delete() - - - operations = [ - migrations.AlterField( - model_name='mailalias', - name='user', - field=models.ForeignKey(help_text='Utilisateur associé', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - migrations.AlterField( - model_name='mailalias', - name='valeur', - field=models.CharField(help_text="Valeur de l'alias mail", max_length=128, unique=True), - ), - migrations.RunPython(transfer_pseudo, untransfer_pseudo), - ] diff --git a/users/models.py b/users/models.py index 4f0b2794..f7e51703 100755 --- a/users/models.py +++ b/users/models.py @@ -53,7 +53,6 @@ from django.db import models from django.db.models import Q from django import forms from django.db.models.signals import post_save, post_delete, m2m_changed -from django.forms import ValidationError from django.dispatch import receiver from django.utils.functional import cached_property from django.template import Context, loader @@ -98,7 +97,7 @@ def linux_user_validator(login): """ Retourne une erreur de validation si le login ne respecte pas les contraintes unix (maj, min, chiffres ou tiret)""" if not linux_user_check(login): - raise ValidationError( + raise forms.ValidationError( ", ce pseudo ('%(label)s') contient des carractères interdits", params={'label': login}, ) @@ -135,7 +134,7 @@ class UserManager(BaseUserManager): self, pseudo, surname, - external_mail, + email, password=None, su=False ): @@ -149,7 +148,7 @@ class UserManager(BaseUserManager): pseudo=pseudo, surname=surname, name=surname, - external_mail=external_mail, + email=self.normalize_email(mail), ) user.set_password(password) @@ -158,19 +157,19 @@ class UserManager(BaseUserManager): user.save(using=self._db) return user - def create_user(self, pseudo, surname, external_mail, password=None): + def create_user(self, pseudo, surname, email, password=None): """ Creates and saves a User with the given pseudo, name, surname, email, and password. """ - return self._create_user(pseudo, surname, external_mail, password, False) + return self._create_user(pseudo, surname, email, password, False) - def create_superuser(self, pseudo, surname, external_mail, password): + def create_superuser(self, pseudo, surname, email, password): """ Creates and saves a superuser with the given pseudo, name, surname, email, and password. """ - return self._create_user(pseudo, surname, external_mail, password, True) + return self._create_user(pseudo, surname, email, password, True) class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, @@ -195,14 +194,14 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, help_text="Doit contenir uniquement des lettres, chiffres, ou tirets", validators=[linux_user_validator] ) - external_mail = models.EmailField() - redirection = models.BooleanField( + email = models.EmailField() + local_email_redirect = models.BooleanField( default=False, - help_text='Activer ou non la redirection du mail interne vers le mail externe' + help_text="Whether or not to redirect the local email messages to the main email." ) - internal_address = models.BooleanField( + local_email_enabled = models.BooleanField( default=False, - help_text='Activer ou non l\'utilisation de l\'adresse mail interne' + help_text="Wether or not to enable the local email account." ) school = models.ForeignKey( 'School', @@ -236,7 +235,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, ) USERNAME_FIELD = 'pseudo' - REQUIRED_FIELDS = ['surname', 'external_mail'] + REQUIRED_FIELDS = ['surname', 'email'] objects = UserManager() @@ -255,9 +254,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, ("view_user", "Peut voir un objet user quelquonque"), ) - - - + @cached_property def name(self): """Si il s'agit d'un adhérent, on renvoie le prénom""" @@ -536,7 +533,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, user_ldap.sn = self.pseudo user_ldap.dialupAccess = str(self.has_access()) user_ldap.home_directory = '/home/' + self.pseudo - user_ldap.mail = self.get_mail() + user_ldap.mail = self.email user_ldap.given_name = self.surname.lower() + '_'\ + self.name.lower()[:3] user_ldap.gid = LDAP['user_gid'] @@ -685,20 +682,12 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, self.pwd_ntlm = hashNT(password) return - def get_mail(self): - """ - Return the mail address choosen by the user - """ - if not OptionalUser.get_cached_value('mail_accounts') or not self.internal_address or self.redirection: - return str(self.external_mail) - else: - return str(self.mailalias_set.get(valeur=self.pseudo)) - @cached_property - def get_mail_aliases(self): - if self.internal_address: - return self.mailalias_set.all() - return None + def local_email_accounts(self): + if (OptionalUser.get_cached_value('local_email_accounts_enabled') + and self.local_email_enabled): + return self.localemailaccount_set.all() + return LocalEmailAccount.objects.none() def get_next_domain_name(self): """Look for an available name for a new interface for @@ -819,20 +808,20 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, ) @staticmethod - def can_change_redirection(user_request, *_args, **_kwargs): - """ Check if a user can change redirection. + 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('mail_accounts'), + OptionalUser.get_cached_value('local_email_accounts_enabled'), "La gestion des comptes mails doit être activée" ) @staticmethod - def can_change_internal_address(user_request, *_args, **_kwargs): + 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 @@ -840,9 +829,9 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, the right to change internal address """ return ( - OptionalUser.get_cached_value('mail_accounts'), + 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): @@ -938,20 +927,23 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, 'shell': self.can_change_shell, 'force': self.can_change_force, 'selfpasswd': self.check_selfpasswd, - 'redirection': self.can_change_redirection, - 'internal_address' : self.can_change_internal_address, + '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 MailAlias.objects.filter(valeur=self.pseudo).exclude(user=self): - raise ValidationError("Ce pseudo est déjà utilisé") + if (LocalEmailAccount.objects + .filter(local_part=self.pseudo) + .exclude(user=self)): + raise ValidationError("This pseudo is already in use.") def __str__(self): return self.pseudo + class Adherent(User): """ A class representing a member (it's a user with special informations) """ @@ -1074,7 +1066,7 @@ def user_post_save(**kwargs): Synchronise le ldap""" is_created = kwargs['created'] user = kwargs['instance'] - mail_alias, created = MailAlias.objects.get_or_create(valeur=user.pseudo, user=user) + LocalEmailAccount.objects.get_or_create(local_part=user.pseudo, user=user) if is_created: user.notif_inscription() user.state_sync() @@ -1656,87 +1648,122 @@ class LdapServiceUserGroup(ldapdb.models.Model): return self.name -class MailAlias(RevMixin, AclMixin, models.Model): - """ - Define a alias for a user Mail - - Définit un alias pour un Mail d'utilisateur +class LocalEmailAccount(RevMixin, AclMixin, models.Model): + """Defines a local email account for a user """ user = models.ForeignKey( User, on_delete=models.CASCADE, - help_text="Utilisateur associé", + help_text="User of the local email", ) - valeur = models.CharField( + local_part = models.CharField( unique=True, max_length=128, - help_text="Valeur de l'alias mail" + help_text="Local part of the email address" ) + class Meta: + permissions = ( + ("view_localemailaccount", "Can see a local email account object"), + ) + verbose_name = "Local email account" + verbose_name_plural = "Local email accounts" + def __str__(self): - return self.valeur + OptionalUser.get_cached_value('mail_extension') + 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 an user can create an mailalias object. + """Check if a user can create a `LocalEmailAccount` object. - :param user_request: The user who wants to create a mailalias object. - :return: a message and a boolean which is True if the user can create - an user or if the `options.all_can_create` is set. + 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 not user_request.has_perm('users.add_mailalias'): - if int(user_request.id) != int(userid): - return False, 'Vous n\'avez pas le droit d\'ajouter un alias à une autre personne' - elif user_request.mailalias_set.all().count() >= OptionalUser.get_cached_value('max_mail_alias'): - return False, "Vous avez atteint la limite de {} alias".format(OptionalUser.get_cached_value('max_mail_alias')) - else: - return True, None + if user_request.has_perm('users.add_localemailaccount'): + 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.local_email_accounts.count() >= OptionalUser.get_cached_value('max_local_email_accounts'): + return False, "You have reached the limit of {} local email account.".format( + OptionalUser.get_cached_value('max_local_email_accounts') + ) return True, None def can_view(self, user_request, *_args, **_kwargs): - """ - Check if the user can view the alias - """ + """Check if a user can view the local email account - if user_request.has_perm('users.view_mailalias') or user.request == self.user: + 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_localemailaccount'): return True, None - else: - return False, "Vous n'avais pas les droits suffisants et n'êtes pas propriétaire de ces alias" - + 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 the user can delete the alias - """ + """Check if a user can delete the alias - if user_request.has_perm('users.delete_mailalias'): + 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_localemailaccount'): return True, None - else: - if user_request == self.user: - if self.valeur != self.user.pseudo: - return True, None - else: - return False, "Vous ne pouvez pas supprimer l'alias lié à votre pseudo" - else: - return False, "Vous n'avez pas les droits suffisants et n'êtes pas propriétairs de ces alias" + 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 the user can edit the alias - """ + """Check if a user can edit the alias - if user_request.has_perm('users.change_mailalias'): + 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_localemailaccount'): return True, None - else: - if user_request == self.user: - if self.valeur != self.user.pseudo: - return True, None - else: - return False, "Vous ne pouvez pas modifier l'alias lié à votre pseudo" - else: - return False, "Vous n'avez pas les droits suffisants et n'êtes pas propriétairs de cet alias" + 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.valeur: - raise ValidationError("Cet alias ne peut contenir un @") - super(MailAlias, self).clean(*args, **kwargs) + if "@" in self.local_part: + raise ValidationError("The local part cannot contain a @") + super(LocalEmailAccount, self).clean(*args, **kwargs) diff --git a/users/templates/users/aff_mailalias.html b/users/templates/users/aff_localemailaccounts.html similarity index 60% rename from users/templates/users/aff_mailalias.html rename to users/templates/users/aff_localemailaccounts.html index a441b9e9..f129d8ab 100644 --- a/users/templates/users/aff_mailalias.html +++ b/users/templates/users/aff_localemailaccounts.html @@ -21,32 +21,36 @@ 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 %} -{% if alias_list.paginator %} +{% load logs_extra %} + +{% if localemailaccount_list.paginator %} {% include "pagination.html" with list=alias_list %} {% endif %} - - - - - - - - {% for alias in alias_list %} - -
Alias
{{ alias }} - {% can_delete alias %} - {% include 'buttons/suppr.html' with href='users:del-mailalias' id=alias.id %} - {% acl_end %} - {% can_edit alias %} - {% include 'buttons/edit.html' with href='users:edit-mailalias' id=alias.id %} + + + + + + + + + {% for localemailaccount in localemailaccount_list %} + + {% endfor %}
Local email address
{{ localemailaccount.complete_email_address }} + {% can_delete localemailaccount %} + {% include 'buttons/suppr.html' with href='users:del-localemailaccount' id=localemailaccount.id %} {% acl_end %} - {% include 'buttons/history.html' with href='users:history' name='mailalias' id=alias.id %} + {% can_edit localemailaccount %} + {% include 'buttons/edit.html' with href='users:edit-localemailaccount' id=localemailaccount.id %} + {% acl_end %} + {% history_button localemailaccount %}
-{% if alias_list.paginator %} +{% if localemailaccount_list.paginator %} {% include "pagination.html" with list=alias_list %} {% endif %} diff --git a/users/templates/users/index_alias.html b/users/templates/users/index_localemailaccount.html similarity index 85% rename from users/templates/users/index_alias.html rename to users/templates/users/index_localemailaccount.html index 52c68733..8ebdb9ec 100644 --- a/users/templates/users/index_alias.html +++ b/users/templates/users/index_localemailaccount.html @@ -25,13 +25,10 @@ with this program; if not, write to the Free Software Foundation, Inc., {% load bootstrap3 %} -{% block title %}Users{% endblock %} +{% block title %}Local email accounts{% endblock %} {% block content %} -

Alias

- {% include "users/aff_alias.html" with alias_list=alias_list %} -
-
-
+

Local email accounts

+ {% include "users/aff_localemailaccounts.html" with localemailaccount_list=localemailaccount_list %} {% endblock %} diff --git a/users/templates/users/profil.html b/users/templates/users/profil.html index 2a67934a..450494af 100644 --- a/users/templates/users/profil.html +++ b/users/templates/users/profil.html @@ -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 %} @@ -408,65 +409,56 @@ with this program; if not, write to the Free Software Foundation, Inc.,
-

- - Paramètres mail -

+

+ Email settings +

{% can_edit users %} - - - Modifier les options mail - + + Edit email settings + {% acl_end %} - {% if mail_accounts %} -
- - - - - - - - - - -
Adresse mail externeCompte mail {{ asso_name }}Adresse mail de contact
{{ users.external_mail }}{{ users.internal_address|yesno:"Activé,Désactivé" }}{{ users.get_mail }}
- -
- {% if users.internal_address %} - {% can_create MailAlias users.id %} - - - Ajouter un alias mail - +
+
+ {% if local_email_accounts_enabled %} +
+ + + + + + + + + + + +
Contact email address{{ users.email }}
Enable the local email account{{ users.local_email_enabled | tick }}Enable the local email redirection{{ users.local_email_redirect | tick }}
+
+ {% if users.local_email_enabled %} + {% can_create LocalEmailAccount users.id %} + + Add a local email account + {% acl_end %} - {% if alias_list %} - {% include "users/aff_mailalias.html" with alias_list=alias_list %} + {% if localemailaccount_list %} + {% include "users/aff_localemailaccounts.html" with localemailaccount_list=localemailaccount_list %} {% endif %} - {% endif %} - {% else %} -
- - - - - - - -
Adresse mail
{{ users.external_mail }}
-
- {% endif %} -
+ {% endif %} + {% else %} +
+ + + + + +
Contact email address{{ users.email }}
+
+ {% endif %} +
-
-
-
{% endblock %} diff --git a/users/urls.py b/users/urls.py index 9289d6c2..0dd4e246 100644 --- a/users/urls.py +++ b/users/urls.py @@ -64,10 +64,18 @@ urlpatterns = [ url(r'^del_whitelist/(?P[0-9]+)$', views.del_whitelist, name='del-whitelist'), - url(r'^add_mailalias/(?P[0-9]+)$', views.add_mailalias, name='add-mailalias'), - url(r'^edit_mailalias/(?P[0-9]+)$', views.edit_mailalias, name='edit-mailalias'), - url(r'^del-mailalias/(?P[0-9]+)$', views.del_mailalias, name='del-mailalias'), - url(r'^edit_mail/(?P[0-9]+)$', views.edit_mail, name='edit-mail'), + url(r'^add_localemailaccount/(?P[0-9]+)$', + views.add_localemailaccount, + name='add-localemailaccount'), + url(r'^edit_localemailaccount/(?P[0-9]+)$', + views.edit_localemailaccount, + name='edit-localemailaccount'), + url(r'^del_localemailaccount/(?P[0-9]+)$', + views.del_localemailaccount, + name='del-localemailaccount'), + url(r'^edit_email_settings/(?P[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[0-9]+)$', views.edit_school, diff --git a/users/views.py b/users/views.py index 3a2b11f7..402cee08 100644 --- a/users/views.py +++ b/users/views.py @@ -81,13 +81,13 @@ from .models import ( Adherent, Club, ListShell, - MailAlias, + LocalEmailAccount, ) from .forms import ( BanForm, WhitelistForm, - MailAliasForm, - MailForm, + LocalEmailAccountForm, + EmailSettingsForm, DelSchoolForm, DelListRightForm, NewListRightForm, @@ -496,90 +496,100 @@ def del_whitelist(request, whitelist, **_kwargs): @login_required -@can_create(MailAlias) +@can_create(LocalEmailAccount) @can_edit(User) -def add_mailalias(request, user, userid): - """ Create a new alias""" - mailalias_instance = MailAlias(user=user) - mailalias = MailAliasForm( +def add_localemailaccount(request, user, userid): + """ Create a new local email account""" + localemailaccount_instance = LocalEmailAccount(user=user) + localemailaccount = LocalEmailAccountForm( request.POST or None, - instance=mailalias_instance + instance=localemailaccount_instance ) - if mailalias.is_valid(): - mailalias.save() - messages.success(request, "Alias created") + if localemailaccount.is_valid(): + localemailaccount.save() + messages.success(request, "Local email account created") return redirect(reverse( 'users:profil', kwargs={'userid': str(userid)} )) return form( - {'userform': mailalias, 'action_name': 'Add an alias mail'}, + {'userform': localemailaccount, + 'showCGU': False, + 'action_name': 'Add a local email account'}, 'users/user.html', request ) + @login_required -@can_edit(MailAlias) -def edit_mailalias(request, mailalias_instance, **_kwargs): - """ Edit a mailalias""" - mailalias = MailAliasForm( +@can_edit(LocalEmailAccount) +def edit_localemailaccount(request, localemailaccount_instance, **_kwargs): + """ Edit a local email account""" + localemailaccount = LocalEmailAccountForm( request.POST or None, - instance=mailalias_instance + instance=localemailaccount_instance ) - if mailalias.is_valid(): - if mailalias.changed_data: - mailalias.save() - messages.success(request, "Alias modified") + if localemailaccount.is_valid(): + if localemailaccount.changed_data: + localemailaccount.save() + messages.success(request, "Local email account modified") return redirect(reverse( 'users:profil', - kwargs={'userid': str(mailalias_instance.user.id)} + kwargs={'userid': str(localemailaccount_instance.user.id)} )) return form( - {'userform': mailalias, 'action_name': 'Edit a mailalias'}, + {'userform': localemailaccount, + 'showCGU': False, + 'action_name': 'Edit a local email account'}, 'users/user.html', request ) + @login_required -@can_delete(MailAlias) -def del_mailalias(request, mailalias, **_kwargs): - """Delete a mail alias""" - if request.method == "POST": - mailalias.delete() - messages.success(request, "Alias deleted") - return redirect(reverse( - 'users:profil', - kwargs={'userid': str(mailalias.user.id)} - )) - return form( - {'objet': mailalias, 'objet_name': 'mailalias'}, - 'users/delete.html', - request - ) +@can_delete(LocalEmailAccount) +def del_localemailaccount(request, localemailaccount, **_kwargs): + """Delete a local email account""" + if request.method == "POST": + localemailaccount.delete() + messages.success(request, "Local email account deleted") + return redirect(reverse( + 'users:profil', + kwargs={'userid': str(localemailaccount.user.id)} + )) + return form( + {'objet': localemailaccount, 'objet_name': 'localemailaccount'}, + 'users/delete.html', + request + ) + @login_required @can_edit(User) -def edit_mail(request, user_instance, **_kwargs): - """ Editer un compte mail""" - mail = MailForm( +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 mail.is_valid(): - if mail.changed_data: - mail.save() - messages.success(request, "Option mail modifiée") + 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': mail, 'action_name': 'Editer les options mail'}, + {'userform': email_settings, + 'showCGU': False, + 'action_name': 'Edit the email settings'}, 'users/user.html', request ) + @login_required @can_create(School) def add_school(request): @@ -1002,10 +1012,11 @@ def profil(request, users, **_kwargs): 'white_list': whitelists, 'user_solde': user_solde, 'solde_activated': Paiement.objects.filter(is_balance=True).exists(), - 'allow_online_payment': allow_online_payment, 'asso_name': AssoOption.objects.first().name, - 'alias_list': users.mailalias_set.all(), - 'mail_accounts': OptionalUser.objects.first().mail_accounts + 'localemailaccount_list': users.local_email_accounts, + 'local_email_accounts_enabled': ( + OptionalUser.objects.first().local_email_accounts_enabled + ) } )