From 27464ffa6f213f51031414de3f120afa2bd864f6 Mon Sep 17 00:00:00 2001 From: Grizzly Date: Tue, 26 Jun 2018 16:46:57 +0000 Subject: [PATCH] =?UTF-8?q?Cr=C3=A9e=20des=20comptes=20mail=20et=20des=20a?= =?UTF-8?q?lias=20mail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- machines/forms.py | 1 + machines/models.py | 4 + re2o/templatetags/acl.py | 1 - users/admin.py | 2 + users/forms.py | 14 +++ users/models.py | 117 ++++++++++++++++++++++++- users/templates/users/aff_alias.html | 53 +++++++++++ users/templates/users/index_alias.html | 37 ++++++++ users/urls.py | 3 + users/views.py | 60 +++++++++++++ 10 files changed, 289 insertions(+), 3 deletions(-) create mode 100644 users/templates/users/aff_alias.html create mode 100644 users/templates/users/index_alias.html diff --git a/machines/forms.py b/machines/forms.py index 23c2aa39..241ce303 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -262,6 +262,7 @@ class ExtensionForm(FormRevMixin, ModelForm): self.fields['origin'].label = 'Enregistrement A origin' self.fields['origin_v6'].label = 'Enregistrement AAAA origin' self.fields['soa'].label = 'En-tête SOA à utiliser' + self.fielss['mail_extension'].label = 'Utilisable comme extension mail' class DelExtensionForm(FormRevMixin, Form): diff --git a/machines/models.py b/machines/models.py index 7be76e74..c8dccadf 100644 --- a/machines/models.py +++ b/machines/models.py @@ -546,6 +546,10 @@ class Extension(RevMixin, AclMixin, models.Model): 'SOA', on_delete=models.CASCADE ) + mail_extension = models.BooleanField( + default=False, + help_text="Determine si l'extension peut être utilisée comme extension mail interne" + ) class Meta: permissions = ( diff --git a/re2o/templatetags/acl.py b/re2o/templatetags/acl.py index fe13c5ac..9a439f88 100644 --- a/re2o/templatetags/acl.py +++ b/re2o/templatetags/acl.py @@ -79,7 +79,6 @@ 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 a902d2e2..5f4c197b 100644 --- a/users/admin.py +++ b/users/admin.py @@ -34,6 +34,8 @@ from reversion.admin import VersionAdmin from .models import ( User, + Mail, + MailAlias, ServiceUser, School, ListRight, diff --git a/users/forms.py b/users/forms.py index 670fbb98..ba8e137e 100644 --- a/users/forms.py +++ b/users/forms.py @@ -53,6 +53,7 @@ from .models import ( School, ListRight, Whitelist, + MailAlias, ListShell, Ban, Adherent, @@ -590,3 +591,16 @@ class WhitelistForm(FormRevMixin, ModelForm): model = Whitelist exclude = ['user'] widgets = {'date_end':DateTimePicker} + + +class MailAliasForm(FormRevMixin, ModelForm): + """Creation, edition d'un objet alias mail""" + 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 = 'nom de l\'adresse mail' + self.fields['extension'].label = 'extension de l\'adresse mail' + + class Meta: + model = MailAlias + exclude = ['mail'] diff --git a/users/models.py b/users/models.py index 067a0346..61f58920 100644 --- a/users/models.py +++ b/users/models.py @@ -79,7 +79,7 @@ from re2o.field_permissions import FieldPermissionModelMixin from re2o.mixins import AclMixin, RevMixin from cotisations.models import Cotisation, Facture, Paiement, Vente -from machines.models import Domain, Interface, Machine, regen +from machines.models import Domain, Interface, Machine, regen, Extension from preferences.models import GeneralOption, AssoOption, OptionalUser from preferences.models import OptionalMachine, MailMessageOption @@ -195,6 +195,12 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser, validators=[linux_user_validator] ) email = models.EmailField() + """ + email= models.OneToOneField( + Mail, + on_delete=models.PROTECT + ) + """ school = models.ForeignKey( 'School', on_delete=models.PROTECT, @@ -246,7 +252,9 @@ 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""" @@ -674,6 +682,15 @@ 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 self.mail.internal_activated: + return(self.mail.external) + else: + return(self.mail.mailalias_set.first()) + def get_next_domain_name(self): """Look for an available name for a new interface for this user by trying "pseudo0", "pseudo1", "pseudo2", ... @@ -1593,3 +1610,99 @@ class LdapServiceUserGroup(ldapdb.models.Model): def __str__(self): return self.name + + +class Mail(RevMixin, AclMixin, models.Model): + """ + Mail account of a user + + Compte mail d'un utilisateur + """ + external_mail = models.EmailField(help_text="Mail externe") + user = models.ForeignKey( + 'User', + on_delete=models.CASCADE, + help_text="Object mail d'un User" + ) + redirection = models.BooleanField( + default=False + ) + internal_address = models.BooleanField( + default=False + ) + + def __str__(self): + return self.mail + + +class MailAlias(RevMixin, AclMixin, models.Model): + """ + Define a alias for a user Mail + + Définit un aliase pour un Mail d'utilisateur + """ + mail = models.ForeignKey( + 'Mail', + on_delete=models.CASCADE, + help_text="Objects Mail associé" + ) + valeur = models.CharField( + max_length=64, + help_text="username de l'adresse mail" + ) + extension = models.ForeignKey( + 'Extension', + on_delete=models.CASCADE, + help_text="Extension mail interne" + ) + + class Meta: + unique_together = ('valeur', 'extension',) + + def __str__(self): + return self.valeur + "@" + self.extension + + def can_view(self, user_request, *_args, **_kwargs): + """ + Check if the user can view the aliases + """ + + if user_request.has_perm('users.view_mailalias') or user.request == self.mail.user: + return True, None + else: + return False, "Vous n'avais pas les droits suffisants et n'êtes pas propriétaire de ces alias" + + def can_delete(self, user_request, *_args, **_kwargs): + """ + Check if the user can delete the alias + """ + + if user_request.has_perm('users.delete_mailalias'): + return True, None + else: + if user_request == self.mail.user: + if self.id != 0: + 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" + + def can_edit(self, user_request, *_args, **_kwargs): + """ + Check if the user can edit the alias + """ + + if user_request.has_perm('users.change_mailalias'): + return True, None + else: + if user_request == self.mail.user: + if self.id != 0: + 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" + + + diff --git a/users/templates/users/aff_alias.html b/users/templates/users/aff_alias.html new file mode 100644 index 00000000..59a9b6f1 --- /dev/null +++ b/users/templates/users/aff_alias.html @@ -0,0 +1,53 @@ +{% 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 %} +{% if alias_list.paginator %} +{% include "pagination.html" with list=alias_list %} +{% endif %} + + + + + + + + + {% for alias in alias_list %} + + + + {% endfor %} +
Alias
{{ alias }} + {% can_delete alias %} + {% include 'buttons/suppr.html' with href='users:del-alias' id=alias.id %} + {% acl_end %} + {% can_edit alias %} + {% include 'buttons/edit.html' with href='users:edit-alias' id=alias.id %} + {% acl_end %} + {% include 'buttons/history.html' with href='users:history' name='alias' id=alias.id %} +
+ +{% if alias_list.paginator %} +{% include "pagination.html" with list=alias_list %} +{% endif %} diff --git a/users/templates/users/index_alias.html b/users/templates/users/index_alias.html new file mode 100644 index 00000000..dc9af095 --- /dev/null +++ b/users/templates/users/index_alias.html @@ -0,0 +1,37 @@ +{% 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 %}Utilisateurs{% endblock %} + +{% block content %} +

Alias

+ {% include "users/aff_alias.html" with alias_list=alias_list %} +
+
+
+{% endblock %} + diff --git a/users/urls.py b/users/urls.py index 6bb374c3..c8284d4e 100644 --- a/users/urls.py +++ b/users/urls.py @@ -64,6 +64,9 @@ 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'^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 a6444e33..b2a83dbe 100644 --- a/users/views.py +++ b/users/views.py @@ -492,6 +492,66 @@ def del_whitelist(request, whitelist, **_kwargs): ) +@login_required +@can_create(MailAlias) +@can_edit(User) +def add_mailalias(request, user, userid): + """ Créer un alias """ + mailalias_instance = MailAlias(mail=user.mail) + whitelist = WhitelistForm( + request.POST or None, + instance=whitelist_instance + ) + if whitelist.is_valid(): + whitelist.save() + messages.success(request, "Alias créé") + return redirect(reverse( + 'users:profil', + kwargs={'userid': str(userid)} + )) + + return form( + {'userform': mailalias, 'action_name': 'Ajouter un alias mail'}, + 'users/user.html', + request + ) + +@login_required +@can_edit(MailAlias) +def edit_mailalias(request, mailalias_instance, **_kwargs): + """ Editer un alias mail""" + mailalias = MailAliasForm( + request.POST or None, + instance=mailalias_instance + ) + if whitelist.is_valid(): + if whitelist.changed_data: + whitelist.save() + messages.success(request, "Alias modifiée") + return redirect(reverse('users:index')) + return form( + {'userform': mailalias, 'action_name': 'Editer un alias mail'}, + 'users/user.html', + request + ) + +@login_required +@can_delete(MailAlias) +def del_mailalias(request, mailalias, **_kwargs): + """ Supprime un alias mail""" + if request.method == "POST": + mailalias.delete() + messages.success(request, "L'alias a été supprimé") + return redirect(reverse( + 'users:profil', + kwargs={'userid': str(mailalias.mail.user.id)} + )) + return form( + {'objet': mailalias, 'objet_name': 'mailalias'}, + 'users/delete.html', + request + ) + @login_required @can_create(School) def add_school(request):