mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-22 11:23:10 +00:00
Cleanup for local email accounts
This commit is contained in:
parent
bd19b27914
commit
43fb83ec12
22 changed files with 587 additions and 599 deletions
44
api/serializers.py
Executable file → Normal file
44
api/serializers.py
Executable file → Normal file
|
@ -492,12 +492,11 @@ class UserSerializer(NamespacedHMSerializer):
|
||||||
"""
|
"""
|
||||||
access = serializers.BooleanField(source='has_access')
|
access = serializers.BooleanField(source='has_access')
|
||||||
uid = serializers.IntegerField(source='uid_number')
|
uid = serializers.IntegerField(source='uid_number')
|
||||||
email = serializers.CharField(source='get_mail')
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = users.User
|
model = users.User
|
||||||
fields = ('name', 'pseudo', 'email', 'school', 'shell', 'comment',
|
fields = ('surname', 'pseudo', 'email', 'local_email_redirect',
|
||||||
'external_mail', 'redirection', 'internal_address',
|
'local_email_enabled', 'school', 'shell', 'comment',
|
||||||
'state', 'registered', 'telephone', 'solde', 'access',
|
'state', 'registered', 'telephone', 'solde', 'access',
|
||||||
'end_access', 'uid', 'class_name', 'api_url')
|
'end_access', 'uid', 'class_name', 'api_url')
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
|
@ -511,12 +510,11 @@ class ClubSerializer(NamespacedHMSerializer):
|
||||||
name = serializers.CharField(source='surname')
|
name = serializers.CharField(source='surname')
|
||||||
access = serializers.BooleanField(source='has_access')
|
access = serializers.BooleanField(source='has_access')
|
||||||
uid = serializers.IntegerField(source='uid_number')
|
uid = serializers.IntegerField(source='uid_number')
|
||||||
email = serializers.CharField(source='get_mail')
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = users.Club
|
model = users.Club
|
||||||
fields = ('name', 'pseudo', 'email', 'school', 'shell', 'comment',
|
fields = ('name', 'pseudo', 'email', 'local_email_redirect',
|
||||||
'external_mail', 'redirection', 'internal_address',
|
'local_email_enabled', 'school', 'shell', 'comment',
|
||||||
'state', 'registered', 'telephone', 'solde', 'room',
|
'state', 'registered', 'telephone', 'solde', 'room',
|
||||||
'access', 'end_access', 'administrators', 'members',
|
'access', 'end_access', 'administrators', 'members',
|
||||||
'mailing', 'uid', 'api_url')
|
'mailing', 'uid', 'api_url')
|
||||||
|
@ -530,14 +528,13 @@ class AdherentSerializer(NamespacedHMSerializer):
|
||||||
"""
|
"""
|
||||||
access = serializers.BooleanField(source='has_access')
|
access = serializers.BooleanField(source='has_access')
|
||||||
uid = serializers.IntegerField(source='uid_number')
|
uid = serializers.IntegerField(source='uid_number')
|
||||||
email = serializers.CharField(source='get_mail')
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = users.Adherent
|
model = users.Adherent
|
||||||
fields = ('name', 'surname', 'pseudo', 'email', 'redirection', 'internal_address',
|
fields = ('name', 'surname', 'pseudo', 'email', 'local_email_redirect',
|
||||||
'external_mail', 'school', 'shell',
|
'local_email_enabled', 'school', 'shell', 'comment',
|
||||||
'comment', 'state', 'registered', 'telephone', 'room',
|
'state', 'registered', 'telephone', 'room', 'solde',
|
||||||
'solde', 'access', 'end_access', 'uid', 'api_url')
|
'access', 'end_access', 'uid', 'api_url')
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'shell': {'view_name': 'shell-detail'}
|
'shell': {'view_name': 'shell-detail'}
|
||||||
}
|
}
|
||||||
|
@ -599,16 +596,13 @@ class WhitelistSerializer(NamespacedHMSerializer):
|
||||||
fields = ('user', 'raison', 'date_start', 'date_end', 'active', 'api_url')
|
fields = ('user', 'raison', 'date_start', 'date_end', 'active', 'api_url')
|
||||||
|
|
||||||
|
|
||||||
class MailAliasSerializer(NamespacedHMSerializer):
|
class LocalEmailAccountSerializer(NamespacedHMSerializer):
|
||||||
"""Serialize `users.models.MailAlias` objects.
|
"""Serialize `users.models.LocalEmailAccount` objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = users.MailAlias
|
model = users.LocalEmailAccount
|
||||||
fields = ('user', 'valeur', 'complete_mail')
|
fields = ('user', 'local_part', 'complete_email_address', 'api_url')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# SERVICE REGEN
|
# SERVICE REGEN
|
||||||
|
@ -628,16 +622,20 @@ class ServiceRegenSerializer(NamespacedHMSerializer):
|
||||||
'api_url': {'view_name': 'serviceregen-detail'}
|
'api_url': {'view_name': 'serviceregen-detail'}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Configuration mail
|
|
||||||
|
# LOCAL EMAILS
|
||||||
|
|
||||||
|
|
||||||
class UserMailAliasSerializer(NamespacedHMSerializer):
|
class LocalEmailUsersSerializer(NamespacedHMSerializer):
|
||||||
get_mail_aliases = MailAliasSerializer(read_only=True, many=True)
|
local_email_accounts = LocalEmailAccountSerializer(
|
||||||
|
read_only=True,
|
||||||
|
many=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = users.User
|
model = users.User
|
||||||
fields = ('pseudo', 'get_mail_aliases')
|
fields = ('local_email_enabled', 'local_email_redirect',
|
||||||
|
'local_email_accounts')
|
||||||
|
|
||||||
|
|
||||||
# DHCP
|
# DHCP
|
||||||
|
|
6
api/urls.py
Executable file → Normal file
6
api/urls.py
Executable file → Normal file
|
@ -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/shell', views.ShellViewSet, base_name='shell')
|
||||||
router.register_viewset(r'users/ban', views.BanViewSet)
|
router.register_viewset(r'users/ban', views.BanViewSet)
|
||||||
router.register_viewset(r'users/whitelist', views.WhitelistViewSet)
|
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
|
# SERVICE REGEN
|
||||||
router.register_viewset(r'services/regen', views.ServiceRegenViewSet, base_name='serviceregen')
|
router.register_viewset(r'services/regen', views.ServiceRegenViewSet, base_name='serviceregen')
|
||||||
# DHCP
|
# DHCP
|
||||||
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
|
router.register_view(r'dhcp/hostmacip', views.HostMacIpView),
|
||||||
# Mail config
|
# LOCAL EMAILS
|
||||||
router.register_view(r'mail/alias', views.UserMailAliasView),
|
router.register_view(r'localemail/users', views.LocalEmailUsersView),
|
||||||
# DNS
|
# DNS
|
||||||
router.register_view(r'dns/zones', views.DNSZonesView),
|
router.register_view(r'dns/zones', views.DNSZonesView),
|
||||||
# MAILING
|
# MAILING
|
||||||
|
|
34
api/views.py
Executable file → Normal file
34
api/views.py
Executable file → Normal file
|
@ -469,11 +469,19 @@ class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
serializer_class = serializers.WhitelistSerializer
|
serializer_class = serializers.WhitelistSerializer
|
||||||
|
|
||||||
|
|
||||||
class MailAliasViewSet(viewsets.ReadOnlyModelViewSet):
|
class LocalEmailAccountViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
"""Exposes list and details of `users.models.MailAlias` objects.
|
"""Exposes list and details of `users.models.LocalEmailAccount` objects.
|
||||||
"""
|
"""
|
||||||
queryset = users.MailAlias.objects.all()
|
serializer_class = serializers.LocalEmailAccountSerializer
|
||||||
serializer_class = serializers.MailAliasSerializer
|
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
|
# SERVICE REGEN
|
||||||
|
@ -496,19 +504,26 @@ class ServiceRegenViewSet(viewsets.ModelViewSet):
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
# Server mail config
|
# LOCAL EMAILS
|
||||||
|
|
||||||
|
|
||||||
class UserMailAliasView(generics.ListAPIView):
|
class LocalEmailUsersView(generics.ListAPIView):
|
||||||
"""Expose all the aliases of the users that activated the internal address
|
"""Exposes all the aliases of the users that activated the internal address
|
||||||
"""
|
"""
|
||||||
|
serializer_class = serializers.LocalEmailUsersSerializer
|
||||||
|
|
||||||
queryset = users.User.objects.filter(internal_address=True)
|
def get_queryset(self):
|
||||||
serializer_class = serializers.UserMailAliasSerializer
|
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
|
# DHCP
|
||||||
|
|
||||||
|
|
||||||
class HostMacIpView(generics.ListAPIView):
|
class HostMacIpView(generics.ListAPIView):
|
||||||
"""Exposes the associations between hostname, mac address and IPv4 in
|
"""Exposes the associations between hostname, mac address and IPv4 in
|
||||||
order to build the DHCP lease files.
|
order to build the DHCP lease files.
|
||||||
|
@ -519,6 +534,7 @@ class HostMacIpView(generics.ListAPIView):
|
||||||
|
|
||||||
# DNS
|
# DNS
|
||||||
|
|
||||||
|
|
||||||
class DNSZonesView(generics.ListAPIView):
|
class DNSZonesView(generics.ListAPIView):
|
||||||
"""Exposes the detailed information about each extension (hostnames,
|
"""Exposes the detailed information about each extension (hostnames,
|
||||||
IPs, DNS records, etc.) in order to build the DNS zone files.
|
IPs, DNS records, etc.) in order to build the DNS zone files.
|
||||||
|
|
|
@ -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),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -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'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -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"),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -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 = [
|
|
||||||
]
|
|
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_local_email_accounts',
|
||||||
|
field=models.IntegerField(default=15, help_text='Maximum number of local email accounts for a standard user'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -30,9 +30,8 @@ from django.db import models
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
||||||
from django.forms import ValidationError
|
from django.forms import ValidationError
|
||||||
import cotisations.models
|
|
||||||
import machines.models
|
import machines.models
|
||||||
from re2o.mixins import AclMixin
|
from re2o.mixins import AclMixin
|
||||||
|
|
||||||
|
@ -85,18 +84,18 @@ class OptionalUser(AclMixin, PreferencesModel):
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
mail_accounts = models.BooleanField(
|
local_email_accounts_enabled = models.BooleanField(
|
||||||
default=False,
|
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,
|
max_length = 32,
|
||||||
default = "@example.org",
|
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,
|
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:
|
class Meta:
|
||||||
|
@ -108,8 +107,8 @@ class OptionalUser(AclMixin, PreferencesModel):
|
||||||
"""Clean model:
|
"""Clean model:
|
||||||
Check the mail_extension
|
Check the mail_extension
|
||||||
"""
|
"""
|
||||||
if self.mail_extension[0] != "@":
|
if self.local_email_domain[0] != "@":
|
||||||
raise ValidationError("Mail extension must begin with @")
|
raise ValidationError("Mail domain must begin with @")
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=OptionalUser)
|
@receiver(post_save, sender=OptionalUser)
|
||||||
|
|
342
preferences/templates/preferences/display_preferences.html
Executable file → Normal file
342
preferences/templates/preferences/display_preferences.html
Executable file → Normal file
|
@ -32,206 +32,204 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h4>Préférences utilisateur</h4>
|
<h4>Préférences utilisateur</h4>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalUser' %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalUser' %}">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i> Editer
|
||||||
Editer
|
</a>
|
||||||
</a>
|
|
||||||
<p>
|
|
||||||
</p>
|
|
||||||
<h5>Généralités</h5>
|
|
||||||
<table class="table table-striped">
|
|
||||||
<tr>
|
|
||||||
<th>Téléphone obligatoirement requis</th>
|
|
||||||
<td>{{ useroptions.is_tel_mandatory|tick }}</td>
|
|
||||||
<th>Auto inscription</th>
|
|
||||||
<td>{{ useroptions.self_adhesion|tick }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Champ gpg fingerprint</th>
|
|
||||||
<td>{{ useroptions.gpg_fingerprint|tick }}</td>
|
|
||||||
<th>Shell par défaut des utilisateurs</th>
|
|
||||||
<td>{{ useroptions.shell_default }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Creations d'adhérents par tous</th>
|
|
||||||
<td>{{ useroptions.all_can_create_adherent|tick }}</td>
|
|
||||||
<th>Creations de clubs par tous</th>
|
|
||||||
<td>{{ useroptions.all_can_create_club|tick }}</td>
|
|
||||||
</tr>
|
|
||||||
<h5>{% if useroptions.mail_accounts %}<span class="label label-success">Comptes mails{% else %}<span class="label label-danger">Comptes mails{% endif%}</span></h5>
|
|
||||||
<table class="table table-striped">
|
|
||||||
<tr>
|
|
||||||
<th>Gestion des comptes mails</th>
|
|
||||||
<td>{{ useroptions.mail_accounts }}</td>
|
|
||||||
<th>Extension mail interne</th>
|
|
||||||
<td>{{ useroptions.mail_extension }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Nombre d'alias maximum</th>
|
|
||||||
<td>{{ useroption.max_mail_alias }}<td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h4>Préférences machines</h4>
|
<h5>Généralités</h5>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalMachine' %}">
|
<table class="table table-striped">
|
||||||
<i class="fa fa-edit"></i>
|
<tr>
|
||||||
Editer
|
<th>Téléphone obligatoirement requis</th>
|
||||||
</a>
|
<td>{{ useroptions.is_tel_mandatory|tick }}</td>
|
||||||
<p>
|
<th>Auto inscription</th>
|
||||||
</p>
|
<td>{{ useroptions.self_adhesion|tick }}</td>
|
||||||
<table class="table table-striped">
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Mot de passe par machine</th>
|
<th>Champ gpg fingerprint</th>
|
||||||
<td>{{ machineoptions.password_machine|tick }}</td>
|
<td>{{ useroptions.gpg_fingerprint|tick }}</td>
|
||||||
<th>Machines/interfaces autorisées par utilisateurs</th>
|
<th>Shell par défaut des utilisateurs</th>
|
||||||
<td>{{ machineoptions.max_lambdauser_interfaces }}</td>
|
<td>{{ useroptions.shell_default }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Alias dns autorisé par utilisateur</th>
|
<th>Creations d'adhérents par tous</th>
|
||||||
<td>{{ machineoptions.max_lambdauser_aliases }}</td>
|
<td>{{ useroptions.all_can_create_adherent|tick }}</td>
|
||||||
<th>Support de l'ipv6</th>
|
<th>Creations de clubs par tous</th>
|
||||||
<td>{{ machineoptions.ipv6_mode }}</td>
|
<td>{{ useroptions.all_can_create_club|tick }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<th>Creation de machines</th>
|
|
||||||
<td>{{ machineoptions.create_machine|tick }}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<h5>Comptes mails</h5>
|
||||||
|
<table class="table table-striped">
|
||||||
|
<tr>
|
||||||
|
<th>Gestion des comptes mails</th>
|
||||||
|
<td>{{ useroptions.local_email_accounts_enabled | tick }}</td>
|
||||||
|
<th>Extension mail interne</th>
|
||||||
|
<td>{{ useroptions.local_email_domain }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Nombre de comptes maximum</th>
|
||||||
|
<td>{{ useroptions.max_local_email_accounts }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
<h4>Préférences machines</h4>
|
||||||
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalMachine' %}">
|
||||||
|
<i class="fa fa-edit"></i> Editer
|
||||||
|
</a>
|
||||||
|
<table class="table table-striped">
|
||||||
|
<tr>
|
||||||
|
<th>Mot de passe par machine</th>
|
||||||
|
<td>{{ machineoptions.password_machine|tick }}</td>
|
||||||
|
<th>Machines/interfaces autorisées par utilisateurs</th>
|
||||||
|
<td>{{ machineoptions.max_lambdauser_interfaces }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Alias dns autorisé par utilisateur</th>
|
||||||
|
<td>{{ machineoptions.max_lambdauser_aliases }}</td>
|
||||||
|
<th>Support de l'ipv6</th>
|
||||||
|
<td>{{ machineoptions.ipv6_mode }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Creation de machines</th>
|
||||||
|
<td>{{ machineoptions.create_machine|tick }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<h4>Préférences topologie</h4>
|
<h4>Préférences topologie</h4>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalTopologie' %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'OptionalTopologie' %}">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i> Editer
|
||||||
Editer
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
|
||||||
</p>
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Politique générale de placement de vlan</th>
|
<th>Politique générale de placement de vlan</th>
|
||||||
<td>{{ topologieoptions.radius_general_policy }}</td>
|
<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>
|
<th>
|
||||||
<td></td>
|
Ce réglage défini la politique vlan après acceptation radius :
|
||||||
</tr>
|
soit sur le vlan de la plage d'ip de la machine, soit sur un
|
||||||
<tr>
|
vlan prédéfini dans "Vlan où placer les machines après acceptation
|
||||||
<th>Vlan où placer les machines après acceptation RADIUS</th>
|
RADIUS"
|
||||||
<td>{{ topologieoptions.vlan_decision_ok }}</td>
|
</th>
|
||||||
<th>Vlan où placer les machines après rejet RADIUS</th>
|
<td></td>
|
||||||
<td>{{ topologieoptions.vlan_decision_nok }}</td>
|
</tr>
|
||||||
</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>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<h4>Préférences generales</h4>
|
<h4>Préférences generales</h4>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'GeneralOption' %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'GeneralOption' %}">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i> Editer
|
||||||
Editer
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
|
||||||
</p>
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nom du site web</th>
|
<th>Nom du site web</th>
|
||||||
<td>{{ generaloptions.site_name }}</td>
|
<td>{{ generaloptions.site_name }}</td>
|
||||||
<th>Adresse mail d'expedition automatique</th>
|
<th>Adresse mail d'expedition automatique</th>
|
||||||
<td>{{ generaloptions.email_from }}</td>
|
<td>{{ generaloptions.email_from }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Affichage de résultats dans le champ de recherche</th>
|
<th>Affichage de résultats dans le champ de recherche</th>
|
||||||
<td>{{ generaloptions.search_display_page }}</td>
|
<td>{{ generaloptions.search_display_page }}</td>
|
||||||
<th>Nombre d'items affichés en liste (taille normale)</th>
|
<th>Nombre d'items affichés en liste (taille normale)</th>
|
||||||
<td>{{ generaloptions.pagination_number }}</td>
|
<td>{{ generaloptions.pagination_number }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nombre d'items affichés en liste (taille élevée)</th>
|
<th>Nombre d'items affichés en liste (taille élevée)</th>
|
||||||
<td>{{ generaloptions.pagination_large_number }}</td>
|
<td>{{ generaloptions.pagination_large_number }}</td>
|
||||||
<th>Temps avant expiration du lien de reinitialisation de mot de passe (en heures)</th>
|
<th>Temps avant expiration du lien de reinitialisation de mot de passe (en heures)</th>
|
||||||
<td>{{ generaloptions.req_expire_hrs }}</td>
|
<td>{{ generaloptions.req_expire_hrs }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Message global affiché sur le site</th>
|
<th>Message global affiché sur le site</th>
|
||||||
<td>{{ generaloptions.general_message }}</td>
|
<td>{{ generaloptions.general_message }}</td>
|
||||||
<th>Résumé des CGU</th>
|
<th>Résumé des CGU</th>
|
||||||
<td>{{ generaloptions.GTU_sum_up }}</td>
|
<td>{{ generaloptions.GTU_sum_up }}</td>
|
||||||
<tr>
|
<tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>CGU</th>
|
<th>CGU</th>
|
||||||
<td>{{generaloptions.GTU}}</th>
|
<td>{{generaloptions.GTU}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<h4>Données de l'association</h4>
|
<h4>Données de l'association</h4>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'AssoOption' %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'AssoOption' %}">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i> Editer
|
||||||
Editer
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
|
||||||
</p>
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<td>{{ assooptions.name }}</td>
|
<td>{{ assooptions.name }}</td>
|
||||||
<th>SIRET</th>
|
<th>SIRET</th>
|
||||||
<td>{{ assooptions.siret }}</td>
|
<td>{{ assooptions.siret }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Adresse</th>
|
<th>Adresse</th>
|
||||||
<td>{{ assooptions.adresse1 }}<br>
|
<td>{{ assooptions.adresse1 }}<br>
|
||||||
{{ assooptions.adresse2 }}</td>
|
{{ assooptions.adresse2 }}</td>
|
||||||
<th>Contact mail</th>
|
<th>Contact mail</th>
|
||||||
<td>{{ assooptions.contact }}</td>
|
<td>{{ assooptions.contact }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Telephone</th>
|
<th>Telephone</th>
|
||||||
<td>{{ assooptions.telephone }}</td>
|
<td>{{ assooptions.telephone }}</td>
|
||||||
<th>Pseudo d'usage</th>
|
<th>Pseudo d'usage</th>
|
||||||
<td>{{ assooptions.pseudo }}</td>
|
<td>{{ assooptions.pseudo }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Objet utilisateur de l'association</th>
|
<th>Objet utilisateur de l'association</th>
|
||||||
<td>{{ assooptions.utilisateur_asso }}</td>
|
<td>{{ assooptions.utilisateur_asso }}</td>
|
||||||
<th>Description de l'association</th>
|
<th>Description de l'association</th>
|
||||||
<td>{{ assooptions.description | safe }}</td>
|
<td>{{ assooptions.description | safe }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<h4>Messages personalisé dans les mails</h4>
|
<h4>Messages personalisé dans les mails</h4>
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'MailMessageOption' %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'MailMessageOption' %}">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i> Editer
|
||||||
Editer
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
|
||||||
</p>
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Mail de bienvenue (Français)</th>
|
<th>Mail de bienvenue (Français)</th>
|
||||||
<td>{{ mailmessageoptions.welcome_mail_fr | safe }}</td>
|
<td>{{ mailmessageoptions.welcome_mail_fr | safe }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Mail de bienvenue (Anglais)</th>
|
<th>Mail de bienvenue (Anglais)</th>
|
||||||
<td>{{ mailmessageoptions.welcome_mail_en | safe }}</td>
|
<td>{{ mailmessageoptions.welcome_mail_en | safe }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</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%}
|
{% 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 %}
|
{% 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 %}
|
{% 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' %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:edit-options' 'HomeOption' %}">
|
||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i> Editer
|
||||||
Editer
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Url du compte twitter</th>
|
<th>Url du compte twitter</th>
|
||||||
<td>{{ homeoptions.twitter_url }}</td>
|
<td>{{ homeoptions.twitter_url }}</td>
|
||||||
<th>Nom utilisé pour afficher le compte</th>
|
<th>Nom utilisé pour afficher le compte</th>
|
||||||
<td>{{ homeoptions.twitter_account_name }}</td>
|
<td>{{ homeoptions.twitter_account_name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Url du compte facebook</th>
|
<th>Url du compte facebook</th>
|
||||||
<td>{{ homeoptions.facebook_url }}</td>
|
<td>{{ homeoptions.facebook_url }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -29,6 +29,7 @@ from django.conf.urls import url
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(
|
url(
|
||||||
r'^edit_options/(?P<section>OptionalUser)$',
|
r'^edit_options/(?P<section>OptionalUser)$',
|
||||||
|
|
|
@ -79,6 +79,7 @@ from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
def get_model(model_name):
|
def get_model(model_name):
|
||||||
"""Retrieve the model object from its name"""
|
"""Retrieve the model object from its name"""
|
||||||
splitted = model_name.split('.')
|
splitted = model_name.split('.')
|
||||||
|
|
|
@ -34,7 +34,7 @@ from reversion.admin import VersionAdmin
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
User,
|
User,
|
||||||
MailAlias,
|
LocalEmailAccount,
|
||||||
ServiceUser,
|
ServiceUser,
|
||||||
School,
|
School,
|
||||||
ListRight,
|
ListRight,
|
||||||
|
@ -109,7 +109,7 @@ class BanAdmin(VersionAdmin):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MailAliasAdmin(VersionAdmin):
|
class LocalEmailAccountAdmin(VersionAdmin):
|
||||||
"""Gestion des alias mail"""
|
"""Gestion des alias mail"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -131,7 +131,9 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
|
||||||
list_display = (
|
list_display = (
|
||||||
'pseudo',
|
'pseudo',
|
||||||
'surname',
|
'surname',
|
||||||
'external_mail',
|
'email',
|
||||||
|
'local_email_redirect',
|
||||||
|
'local_email_enabled',
|
||||||
'school',
|
'school',
|
||||||
'is_admin',
|
'is_admin',
|
||||||
'shell'
|
'shell'
|
||||||
|
@ -145,7 +147,7 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
|
||||||
'Personal info',
|
'Personal info',
|
||||||
{
|
{
|
||||||
'fields':
|
'fields':
|
||||||
('surname', 'external_mail', 'school', 'shell', 'uid_number')
|
('surname', 'email', 'school', 'shell', 'uid_number')
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
('Permissions', {'fields': ('is_admin', )}),
|
('Permissions', {'fields': ('is_admin', )}),
|
||||||
|
@ -160,7 +162,7 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
|
||||||
'fields': (
|
'fields': (
|
||||||
'pseudo',
|
'pseudo',
|
||||||
'surname',
|
'surname',
|
||||||
'external_mail',
|
'email',
|
||||||
'school',
|
'school',
|
||||||
'is_admin',
|
'is_admin',
|
||||||
'password1',
|
'password1',
|
||||||
|
@ -217,7 +219,7 @@ admin.site.register(School, SchoolAdmin)
|
||||||
admin.site.register(ListRight, ListRightAdmin)
|
admin.site.register(ListRight, ListRightAdmin)
|
||||||
admin.site.register(ListShell, ListShellAdmin)
|
admin.site.register(ListShell, ListShellAdmin)
|
||||||
admin.site.register(Ban, BanAdmin)
|
admin.site.register(Ban, BanAdmin)
|
||||||
admin.site.register(MailAlias, MailAliasAdmin)
|
admin.site.register(LocalEmailAccount, LocalEmailAccountAdmin)
|
||||||
admin.site.register(Whitelist, WhitelistAdmin)
|
admin.site.register(Whitelist, WhitelistAdmin)
|
||||||
admin.site.register(Request, RequestAdmin)
|
admin.site.register(Request, RequestAdmin)
|
||||||
# Now register the new UserAdmin...
|
# Now register the new UserAdmin...
|
||||||
|
|
|
@ -53,7 +53,7 @@ from .models import (
|
||||||
School,
|
School,
|
||||||
ListRight,
|
ListRight,
|
||||||
Whitelist,
|
Whitelist,
|
||||||
MailAlias,
|
LocalEmailAccount,
|
||||||
ListShell,
|
ListShell,
|
||||||
Ban,
|
Ban,
|
||||||
Adherent,
|
Adherent,
|
||||||
|
@ -140,7 +140,7 @@ class UserCreationForm(FormRevMixin, forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Adherent
|
model = Adherent
|
||||||
fields = ('pseudo', 'surname')
|
fields = ('pseudo', 'surname', 'email')
|
||||||
|
|
||||||
def clean_password2(self):
|
def clean_password2(self):
|
||||||
"""Verifie que password1 et 2 sont identiques"""
|
"""Verifie que password1 et 2 sont identiques"""
|
||||||
|
@ -306,6 +306,7 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
self.fields['room'].label = 'Chambre'
|
self.fields['room'].label = 'Chambre'
|
||||||
self.fields['room'].empty_label = "Pas de chambre"
|
self.fields['room'].empty_label = "Pas de chambre"
|
||||||
self.fields['school'].empty_label = "Séléctionner un établissement"
|
self.fields['school'].empty_label = "Séléctionner un établissement"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Adherent
|
model = Adherent
|
||||||
fields = [
|
fields = [
|
||||||
|
@ -590,28 +591,37 @@ class WhitelistForm(FormRevMixin, ModelForm):
|
||||||
widgets = {'date_end':DateTimePicker}
|
widgets = {'date_end':DateTimePicker}
|
||||||
|
|
||||||
|
|
||||||
class MailAliasForm(FormRevMixin, ModelForm):
|
class LocalEmailAccountForm(FormRevMixin, ModelForm):
|
||||||
"""Create and edit a mailalias"""
|
"""Create and edit a local email account"""
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||||
super(MailAliasForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(LocalEmailAccountForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['valeur'].label = "Prefix of mailalias. Can't contain @"
|
self.fields['local_part'].label = "Local part of the email"
|
||||||
|
self.fields['local_part'].help_text = "Can't contain @"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = MailAlias
|
model = LocalEmailAccount
|
||||||
exclude = ['user']
|
exclude = ['user']
|
||||||
|
|
||||||
class MailForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
|
||||||
"""Edit mail settings"""
|
class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
|
"""Edit email-related settings"""
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
|
||||||
super(MailForm, self).__init__(*args, prefix=prefix, **kwargs)
|
super(EmailSettingsForm, self).__init__(*args, prefix=prefix, **kwargs)
|
||||||
self.fields['external_mail'].label = 'External mail address'
|
self.fields['email'].label = "Contact email address"
|
||||||
if 'redirection' in self.fields:
|
if 'local_email_redirect' in self.fields:
|
||||||
self.fields['redirection'].label = 'Enable redirect to external address'
|
self.fields['local_email_redirect'].label = "Redirect local emails"
|
||||||
if 'internal_address' in self.fields:
|
self.fields['local_email_redirect'].help_text = (
|
||||||
self.fields['internal_address'].label = 'Internal mail address'
|
"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:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ['external_mail', 'redirection', 'internal_address']
|
fields = ['email', 'local_email_redirect', 'local_email_enabled']
|
||||||
|
|
|
@ -10,37 +10,49 @@ import re2o.mixins
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
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 = [
|
dependencies = [
|
||||||
('users', '0072_auto_20180426_2021'),
|
('users', '0072_auto_20180426_2021'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='MailAlias',
|
name='LocalEmailAccount',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('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),
|
bases=(re2o.mixins.RevMixin, re2o.mixins.AclMixin, models.Model),
|
||||||
),
|
options={'permissions': (('view_localemailaccount', 'Can see a local email account object'),), 'verbose_name': 'Local email account', 'verbose_name_plural': 'Local email accounts'},
|
||||||
migrations.RenameField(
|
|
||||||
model_name='user',
|
|
||||||
old_name='email',
|
|
||||||
new_name='external_mail',
|
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='user',
|
model_name='user',
|
||||||
name='internal_address',
|
name='local_email_enabled',
|
||||||
field=models.BooleanField(default=False, help_text="Activer ou non l'utilisation de l'adresse mail interne"),
|
field=models.BooleanField(default=False, help_text="Wether or not to enable the local email account."),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='user',
|
model_name='user',
|
||||||
name='redirection',
|
name='local_email_redirect',
|
||||||
field=models.BooleanField(default=False, help_text='Activer ou non la redirection du mail interne vers le mail externe'),
|
field=models.BooleanField(default=False, help_text='Whether or not to redirect the local email messages to the main email.'),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.RunPython(create_initial_local_email_account,
|
||||||
model_name='mailalias',
|
delete_all_local_email_accounts),
|
||||||
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),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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),
|
|
||||||
]
|
|
213
users/models.py
213
users/models.py
|
@ -53,7 +53,6 @@ from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.db.models.signals import post_save, post_delete, m2m_changed
|
from django.db.models.signals import post_save, post_delete, m2m_changed
|
||||||
from django.forms import ValidationError
|
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.template import Context, loader
|
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
|
""" Retourne une erreur de validation si le login ne respecte
|
||||||
pas les contraintes unix (maj, min, chiffres ou tiret)"""
|
pas les contraintes unix (maj, min, chiffres ou tiret)"""
|
||||||
if not linux_user_check(login):
|
if not linux_user_check(login):
|
||||||
raise ValidationError(
|
raise forms.ValidationError(
|
||||||
", ce pseudo ('%(label)s') contient des carractères interdits",
|
", ce pseudo ('%(label)s') contient des carractères interdits",
|
||||||
params={'label': login},
|
params={'label': login},
|
||||||
)
|
)
|
||||||
|
@ -135,7 +134,7 @@ class UserManager(BaseUserManager):
|
||||||
self,
|
self,
|
||||||
pseudo,
|
pseudo,
|
||||||
surname,
|
surname,
|
||||||
external_mail,
|
email,
|
||||||
password=None,
|
password=None,
|
||||||
su=False
|
su=False
|
||||||
):
|
):
|
||||||
|
@ -149,7 +148,7 @@ class UserManager(BaseUserManager):
|
||||||
pseudo=pseudo,
|
pseudo=pseudo,
|
||||||
surname=surname,
|
surname=surname,
|
||||||
name=surname,
|
name=surname,
|
||||||
external_mail=external_mail,
|
email=self.normalize_email(mail),
|
||||||
)
|
)
|
||||||
|
|
||||||
user.set_password(password)
|
user.set_password(password)
|
||||||
|
@ -158,19 +157,19 @@ class UserManager(BaseUserManager):
|
||||||
user.save(using=self._db)
|
user.save(using=self._db)
|
||||||
return user
|
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,
|
Creates and saves a User with the given pseudo, name, surname, email,
|
||||||
and password.
|
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,
|
Creates and saves a superuser with the given pseudo, name, surname,
|
||||||
email, and password.
|
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,
|
class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
||||||
|
@ -195,14 +194,14 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
||||||
help_text="Doit contenir uniquement des lettres, chiffres, ou tirets",
|
help_text="Doit contenir uniquement des lettres, chiffres, ou tirets",
|
||||||
validators=[linux_user_validator]
|
validators=[linux_user_validator]
|
||||||
)
|
)
|
||||||
external_mail = models.EmailField()
|
email = models.EmailField()
|
||||||
redirection = models.BooleanField(
|
local_email_redirect = models.BooleanField(
|
||||||
default=False,
|
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,
|
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 = models.ForeignKey(
|
||||||
'School',
|
'School',
|
||||||
|
@ -236,7 +235,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
||||||
)
|
)
|
||||||
|
|
||||||
USERNAME_FIELD = 'pseudo'
|
USERNAME_FIELD = 'pseudo'
|
||||||
REQUIRED_FIELDS = ['surname', 'external_mail']
|
REQUIRED_FIELDS = ['surname', 'email']
|
||||||
|
|
||||||
objects = UserManager()
|
objects = UserManager()
|
||||||
|
|
||||||
|
@ -256,8 +255,6 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
||||||
"Peut voir un objet user quelquonque"),
|
"Peut voir un objet user quelquonque"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Si il s'agit d'un adhérent, on renvoie le prénom"""
|
"""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.sn = self.pseudo
|
||||||
user_ldap.dialupAccess = str(self.has_access())
|
user_ldap.dialupAccess = str(self.has_access())
|
||||||
user_ldap.home_directory = '/home/' + self.pseudo
|
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() + '_'\
|
user_ldap.given_name = self.surname.lower() + '_'\
|
||||||
+ self.name.lower()[:3]
|
+ self.name.lower()[:3]
|
||||||
user_ldap.gid = LDAP['user_gid']
|
user_ldap.gid = LDAP['user_gid']
|
||||||
|
@ -685,20 +682,12 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
||||||
self.pwd_ntlm = hashNT(password)
|
self.pwd_ntlm = hashNT(password)
|
||||||
return
|
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
|
@cached_property
|
||||||
def get_mail_aliases(self):
|
def local_email_accounts(self):
|
||||||
if self.internal_address:
|
if (OptionalUser.get_cached_value('local_email_accounts_enabled')
|
||||||
return self.mailalias_set.all()
|
and self.local_email_enabled):
|
||||||
return None
|
return self.localemailaccount_set.all()
|
||||||
|
return LocalEmailAccount.objects.none()
|
||||||
|
|
||||||
def get_next_domain_name(self):
|
def get_next_domain_name(self):
|
||||||
"""Look for an available name for a new interface for
|
"""Look for an available name for a new interface for
|
||||||
|
@ -819,20 +808,20 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def can_change_redirection(user_request, *_args, **_kwargs):
|
def can_change_local_email_redirect(user_request, *_args, **_kwargs):
|
||||||
""" Check if a user can change redirection.
|
""" Check if a user can change local_email_redirect.
|
||||||
|
|
||||||
:param user_request: The user who request
|
:param user_request: The user who request
|
||||||
:returns: a message and a boolean which is True if the user has
|
:returns: a message and a boolean which is True if the user has
|
||||||
the right to change a redirection
|
the right to change a redirection
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
OptionalUser.get_cached_value('mail_accounts'),
|
OptionalUser.get_cached_value('local_email_accounts_enabled'),
|
||||||
"La gestion des comptes mails doit être activée"
|
"La gestion des comptes mails doit être activée"
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@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 .
|
""" Check if a user can change internal address .
|
||||||
|
|
||||||
:param user_request: The user who request
|
:param user_request: The user who request
|
||||||
|
@ -840,7 +829,7 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
||||||
the right to change internal address
|
the right to change internal address
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
OptionalUser.get_cached_value('mail_accounts'),
|
OptionalUser.get_cached_value('local_email_accounts_enabled'),
|
||||||
"La gestion des comptes mails doit être activée"
|
"La gestion des comptes mails doit être activée"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -938,20 +927,23 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
||||||
'shell': self.can_change_shell,
|
'shell': self.can_change_shell,
|
||||||
'force': self.can_change_force,
|
'force': self.can_change_force,
|
||||||
'selfpasswd': self.check_selfpasswd,
|
'selfpasswd': self.check_selfpasswd,
|
||||||
'redirection': self.can_change_redirection,
|
'local_email_redirect': self.can_change_local_email_redirect,
|
||||||
'internal_address' : self.can_change_internal_address,
|
'local_email_enabled' : self.can_change_local_email_enabled,
|
||||||
}
|
}
|
||||||
self.__original_state = self.state
|
self.__original_state = self.state
|
||||||
|
|
||||||
def clean(self, *args, **kwargs):
|
def clean(self, *args, **kwargs):
|
||||||
"""Check if this pseudo is already used by any mailalias.
|
"""Check if this pseudo is already used by any mailalias.
|
||||||
Better than raising an error in post-save and catching it"""
|
Better than raising an error in post-save and catching it"""
|
||||||
if MailAlias.objects.filter(valeur=self.pseudo).exclude(user=self):
|
if (LocalEmailAccount.objects
|
||||||
raise ValidationError("Ce pseudo est déjà utilisé")
|
.filter(local_part=self.pseudo)
|
||||||
|
.exclude(user=self)):
|
||||||
|
raise ValidationError("This pseudo is already in use.")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.pseudo
|
return self.pseudo
|
||||||
|
|
||||||
|
|
||||||
class Adherent(User):
|
class Adherent(User):
|
||||||
""" A class representing a member (it's a user with special
|
""" A class representing a member (it's a user with special
|
||||||
informations) """
|
informations) """
|
||||||
|
@ -1074,7 +1066,7 @@ def user_post_save(**kwargs):
|
||||||
Synchronise le ldap"""
|
Synchronise le ldap"""
|
||||||
is_created = kwargs['created']
|
is_created = kwargs['created']
|
||||||
user = kwargs['instance']
|
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:
|
if is_created:
|
||||||
user.notif_inscription()
|
user.notif_inscription()
|
||||||
user.state_sync()
|
user.state_sync()
|
||||||
|
@ -1656,87 +1648,122 @@ class LdapServiceUserGroup(ldapdb.models.Model):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class MailAlias(RevMixin, AclMixin, models.Model):
|
class LocalEmailAccount(RevMixin, AclMixin, models.Model):
|
||||||
"""
|
"""Defines a local email account for a user
|
||||||
Define a alias for a user Mail
|
|
||||||
|
|
||||||
Définit un alias pour un Mail d'utilisateur
|
|
||||||
"""
|
"""
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
User,
|
User,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
help_text="Utilisateur associé",
|
help_text="User of the local email",
|
||||||
)
|
)
|
||||||
valeur = models.CharField(
|
local_part = models.CharField(
|
||||||
unique=True,
|
unique=True,
|
||||||
max_length=128,
|
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):
|
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
|
@staticmethod
|
||||||
def can_create(user_request, userid, *_args, **_kwargs):
|
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.
|
Args:
|
||||||
:return: a message and a boolean which is True if the user can create
|
user_request: The user who wants to create the object.
|
||||||
an user or if the `options.all_can_create` is set.
|
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 user_request.has_perm('users.add_localemailaccount'):
|
||||||
if int(user_request.id) != int(userid):
|
return True, None
|
||||||
return False, 'Vous n\'avez pas le droit d\'ajouter un alias à une autre personne'
|
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
|
||||||
elif user_request.mailalias_set.all().count() >= OptionalUser.get_cached_value('max_mail_alias'):
|
return False, "The local email accounts are not enabled."
|
||||||
return False, "Vous avez atteint la limite de {} alias".format(OptionalUser.get_cached_value('max_mail_alias'))
|
if int(user_request.id) != int(userid):
|
||||||
else:
|
return False, "You don't have the right to add a local email account to another user."
|
||||||
return True, None
|
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
|
return True, None
|
||||||
|
|
||||||
def can_view(self, user_request, *_args, **_kwargs):
|
def can_view(self, user_request, *_args, **_kwargs):
|
||||||
"""
|
"""Check if a user can view the local email account
|
||||||
Check if the user can view the alias
|
|
||||||
"""
|
|
||||||
|
|
||||||
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
|
return True, None
|
||||||
else:
|
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
|
||||||
return False, "Vous n'avais pas les droits suffisants et n'êtes pas propriétaire de ces alias"
|
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):
|
def can_delete(self, user_request, *_args, **_kwargs):
|
||||||
"""
|
"""Check if a user can delete the alias
|
||||||
Check if the 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
|
return True, None
|
||||||
else:
|
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
|
||||||
if user_request == self.user:
|
return False, "The local email accounts are not enabled."
|
||||||
if self.valeur != self.user.pseudo:
|
if user_request == self.user:
|
||||||
return True, None
|
return True, None
|
||||||
else:
|
return False, ("You don't have the right to delete someone else's "
|
||||||
return False, "Vous ne pouvez pas supprimer l'alias lié à votre pseudo"
|
"local email account")
|
||||||
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):
|
def can_edit(self, user_request, *_args, **_kwargs):
|
||||||
"""
|
"""Check if a user can edit the alias
|
||||||
Check if the 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
|
return True, None
|
||||||
else:
|
if not OptionalUser.get_cached_value('local_email_accounts_enabled'):
|
||||||
if user_request == self.user:
|
return False, "The local email accounts are not enabled."
|
||||||
if self.valeur != self.user.pseudo:
|
if user_request == self.user:
|
||||||
return True, None
|
return True, None
|
||||||
else:
|
return False, ("You don't have the right to edit someone else's "
|
||||||
return False, "Vous ne pouvez pas modifier l'alias lié à votre pseudo"
|
"local email account")
|
||||||
else:
|
|
||||||
return False, "Vous n'avez pas les droits suffisants et n'êtes pas propriétairs de cet alias"
|
|
||||||
|
|
||||||
def clean(self, *args, **kwargs):
|
def clean(self, *args, **kwargs):
|
||||||
if "@" in self.valeur:
|
if "@" in self.local_part:
|
||||||
raise ValidationError("Cet alias ne peut contenir un @")
|
raise ValidationError("The local part cannot contain a @")
|
||||||
super(MailAlias, self).clean(*args, **kwargs)
|
super(LocalEmailAccount, self).clean(*args, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -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.,
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
|
|
||||||
{% load acl %}
|
{% load acl %}
|
||||||
{% if alias_list.paginator %}
|
{% load logs_extra %}
|
||||||
|
|
||||||
|
{% if localemailaccount_list.paginator %}
|
||||||
{% include "pagination.html" with list=alias_list %}
|
{% include "pagination.html" with list=alias_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<table class="table table-striped">
|
|
||||||
<thead>
|
<table class="table table-striped">
|
||||||
<tr>
|
<thead>
|
||||||
<th>Alias</th>
|
<tr>
|
||||||
<th></th>
|
<th>Local email address</th>
|
||||||
</tr>
|
<th></th>
|
||||||
</thead>
|
</tr>
|
||||||
{% for alias in alias_list %}
|
</thead>
|
||||||
<td>{{ alias }}</td>
|
{% for localemailaccount in localemailaccount_list %}
|
||||||
<td class="text-right">
|
<td>{{ localemailaccount.complete_email_address }}</td>
|
||||||
{% can_delete alias %}
|
<td class="text-right">
|
||||||
{% include 'buttons/suppr.html' with href='users:del-mailalias' id=alias.id %}
|
{% can_delete localemailaccount %}
|
||||||
{% acl_end %}
|
{% include 'buttons/suppr.html' with href='users:del-localemailaccount' id=localemailaccount.id %}
|
||||||
{% can_edit alias %}
|
|
||||||
{% include 'buttons/edit.html' with href='users:edit-mailalias' id=alias.id %}
|
|
||||||
{% acl_end %}
|
{% 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 %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{% if alias_list.paginator %}
|
{% if localemailaccount_list.paginator %}
|
||||||
{% include "pagination.html" with list=alias_list %}
|
{% include "pagination.html" with list=alias_list %}
|
||||||
{% endif %}
|
{% endif %}
|
|
@ -25,13 +25,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
|
|
||||||
{% block title %}Users{% endblock %}
|
{% block title %}Local email accounts{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>Alias</h2>
|
<h2>Local email accounts</h2>
|
||||||
{% include "users/aff_alias.html" with alias_list=alias_list %}
|
{% include "users/aff_localemailaccounts.html" with localemailaccount_list=localemailaccount_list %}
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
{% load acl %}
|
{% load acl %}
|
||||||
{% load logs_extra %}
|
{% load logs_extra %}
|
||||||
|
{% load design %}
|
||||||
|
|
||||||
{% block title %}Profil{% endblock %}
|
{% block title %}Profil{% endblock %}
|
||||||
|
|
||||||
|
@ -408,65 +409,56 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading clearfix" data-parent="#accordion" data-toggle="collapse" data-target="#collapse7">
|
<div class="panel-heading clearfix" data-parent="#accordion" data-toggle="collapse" data-target="#collapse7">
|
||||||
<h3 class="panel-title pull-left">
|
<h3 class="panel-title pull-left">
|
||||||
<i class="fa fa-envelope"></i>
|
<i class="fa fa-envelope"></i> Email settings
|
||||||
Paramètres mail
|
</h3>
|
||||||
</h3>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="collapse7" class="panel-collapse collapse">
|
<div id="collapse7" class="panel-collapse collapse">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% can_edit users %}
|
{% can_edit users %}
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-mail' users.id %}">
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:edit-email-settings' users.id %}">
|
||||||
<i class="fa fa-plus-square"></i>
|
<i class="fa fa-pencil-alt"></i> Edit email settings
|
||||||
Modifier les options mail
|
</a>
|
||||||
</a>
|
|
||||||
{% acl_end %}
|
{% acl_end %}
|
||||||
{% if mail_accounts %}
|
</div>
|
||||||
<div class="table-responsive">
|
<div class="panel-body">
|
||||||
<table class="table">
|
{% if local_email_accounts_enabled %}
|
||||||
<tr>
|
<div class="table-responsive">
|
||||||
<th>Adresse mail externe</th>
|
<table class="table">
|
||||||
<th>Compte mail {{ asso_name }}</th>
|
<tr>
|
||||||
<th>Adresse mail de contact</th>
|
<th colspan="2">Contact email address</th>
|
||||||
</tr>
|
<td colspan="2">{{ users.email }}</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>{{ users.external_mail }}</td>
|
<tr>
|
||||||
<td>{{ users.internal_address|yesno:"Activé,Désactivé" }}</td>
|
<th>Enable the local email account</th>
|
||||||
<td>{{ users.get_mail }}</td>
|
<td>{{ users.local_email_enabled | tick }}</td>
|
||||||
</table>
|
<th>Enable the local email redirection</th>
|
||||||
<div class="alert alert-info" role="alert">
|
<td>{{ users.local_email_redirect | tick }}</td>
|
||||||
Vous pouvez bénéficier d'une adresse mail {{ asso_name }}.
|
</tr>
|
||||||
Vous pouvez également la rediriger vers une adresse externe en modifiant les options mail.
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% if users.local_email_enabled %}
|
||||||
{% if users.internal_address %}
|
{% can_create LocalEmailAccount users.id %}
|
||||||
{% can_create MailAlias users.id %}
|
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:add-localemailaccount' users.id %}">
|
||||||
<a class="btn btn-primary btn-sm" role="button" href="{% url 'users:add-mailalias' users.id %}">
|
<i class="fa fa-plus-square"></i> Add a local email account
|
||||||
<i class="fa fa-plus-square"></i>
|
</a>
|
||||||
Ajouter un alias mail
|
|
||||||
</a>
|
|
||||||
{% acl_end %}
|
{% acl_end %}
|
||||||
{% if alias_list %}
|
{% if localemailaccount_list %}
|
||||||
{% include "users/aff_mailalias.html" with alias_list=alias_list %}
|
{% include "users/aff_localemailaccounts.html" with localemailaccount_list=localemailaccount_list %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Adresse mail</th>
|
<th>Contact email address</th>
|
||||||
</tr>
|
<td>{{ users.email }}</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>{{ users.external_mail }}</td>
|
</table>
|
||||||
</tr>
|
</div>
|
||||||
</table>
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -64,10 +64,18 @@ urlpatterns = [
|
||||||
url(r'^del_whitelist/(?P<whitelistid>[0-9]+)$',
|
url(r'^del_whitelist/(?P<whitelistid>[0-9]+)$',
|
||||||
views.del_whitelist,
|
views.del_whitelist,
|
||||||
name='del-whitelist'),
|
name='del-whitelist'),
|
||||||
url(r'^add_mailalias/(?P<userid>[0-9]+)$', views.add_mailalias, name='add-mailalias'),
|
url(r'^add_localemailaccount/(?P<userid>[0-9]+)$',
|
||||||
url(r'^edit_mailalias/(?P<mailaliasid>[0-9]+)$', views.edit_mailalias, name='edit-mailalias'),
|
views.add_localemailaccount,
|
||||||
url(r'^del-mailalias/(?P<mailaliasid>[0-9]+)$', views.del_mailalias, name='del-mailalias'),
|
name='add-localemailaccount'),
|
||||||
url(r'^edit_mail/(?P<userid>[0-9]+)$', views.edit_mail, name='edit-mail'),
|
url(r'^edit_localemailaccount/(?P<localemailaccountid>[0-9]+)$',
|
||||||
|
views.edit_localemailaccount,
|
||||||
|
name='edit-localemailaccount'),
|
||||||
|
url(r'^del_localemailaccount/(?P<localemailaccountid>[0-9]+)$',
|
||||||
|
views.del_localemailaccount,
|
||||||
|
name='del-localemailaccount'),
|
||||||
|
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'^add_school/$', views.add_school, name='add-school'),
|
||||||
url(r'^edit_school/(?P<schoolid>[0-9]+)$',
|
url(r'^edit_school/(?P<schoolid>[0-9]+)$',
|
||||||
views.edit_school,
|
views.edit_school,
|
||||||
|
|
111
users/views.py
111
users/views.py
|
@ -81,13 +81,13 @@ from .models import (
|
||||||
Adherent,
|
Adherent,
|
||||||
Club,
|
Club,
|
||||||
ListShell,
|
ListShell,
|
||||||
MailAlias,
|
LocalEmailAccount,
|
||||||
)
|
)
|
||||||
from .forms import (
|
from .forms import (
|
||||||
BanForm,
|
BanForm,
|
||||||
WhitelistForm,
|
WhitelistForm,
|
||||||
MailAliasForm,
|
LocalEmailAccountForm,
|
||||||
MailForm,
|
EmailSettingsForm,
|
||||||
DelSchoolForm,
|
DelSchoolForm,
|
||||||
DelListRightForm,
|
DelListRightForm,
|
||||||
NewListRightForm,
|
NewListRightForm,
|
||||||
|
@ -496,90 +496,100 @@ def del_whitelist(request, whitelist, **_kwargs):
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_create(MailAlias)
|
@can_create(LocalEmailAccount)
|
||||||
@can_edit(User)
|
@can_edit(User)
|
||||||
def add_mailalias(request, user, userid):
|
def add_localemailaccount(request, user, userid):
|
||||||
""" Create a new alias"""
|
""" Create a new local email account"""
|
||||||
mailalias_instance = MailAlias(user=user)
|
localemailaccount_instance = LocalEmailAccount(user=user)
|
||||||
mailalias = MailAliasForm(
|
localemailaccount = LocalEmailAccountForm(
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
instance=mailalias_instance
|
instance=localemailaccount_instance
|
||||||
)
|
)
|
||||||
if mailalias.is_valid():
|
if localemailaccount.is_valid():
|
||||||
mailalias.save()
|
localemailaccount.save()
|
||||||
messages.success(request, "Alias created")
|
messages.success(request, "Local email account created")
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'users:profil',
|
'users:profil',
|
||||||
kwargs={'userid': str(userid)}
|
kwargs={'userid': str(userid)}
|
||||||
))
|
))
|
||||||
return form(
|
return form(
|
||||||
{'userform': mailalias, 'action_name': 'Add an alias mail'},
|
{'userform': localemailaccount,
|
||||||
|
'showCGU': False,
|
||||||
|
'action_name': 'Add a local email account'},
|
||||||
'users/user.html',
|
'users/user.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_edit(MailAlias)
|
@can_edit(LocalEmailAccount)
|
||||||
def edit_mailalias(request, mailalias_instance, **_kwargs):
|
def edit_localemailaccount(request, localemailaccount_instance, **_kwargs):
|
||||||
""" Edit a mailalias"""
|
""" Edit a local email account"""
|
||||||
mailalias = MailAliasForm(
|
localemailaccount = LocalEmailAccountForm(
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
instance=mailalias_instance
|
instance=localemailaccount_instance
|
||||||
)
|
)
|
||||||
if mailalias.is_valid():
|
if localemailaccount.is_valid():
|
||||||
if mailalias.changed_data:
|
if localemailaccount.changed_data:
|
||||||
mailalias.save()
|
localemailaccount.save()
|
||||||
messages.success(request, "Alias modified")
|
messages.success(request, "Local email account modified")
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'users:profil',
|
'users:profil',
|
||||||
kwargs={'userid': str(mailalias_instance.user.id)}
|
kwargs={'userid': str(localemailaccount_instance.user.id)}
|
||||||
))
|
))
|
||||||
return form(
|
return form(
|
||||||
{'userform': mailalias, 'action_name': 'Edit a mailalias'},
|
{'userform': localemailaccount,
|
||||||
|
'showCGU': False,
|
||||||
|
'action_name': 'Edit a local email account'},
|
||||||
'users/user.html',
|
'users/user.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_delete(MailAlias)
|
@can_delete(LocalEmailAccount)
|
||||||
def del_mailalias(request, mailalias, **_kwargs):
|
def del_localemailaccount(request, localemailaccount, **_kwargs):
|
||||||
"""Delete a mail alias"""
|
"""Delete a local email account"""
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
mailalias.delete()
|
localemailaccount.delete()
|
||||||
messages.success(request, "Alias deleted")
|
messages.success(request, "Local email account deleted")
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'users:profil',
|
'users:profil',
|
||||||
kwargs={'userid': str(mailalias.user.id)}
|
kwargs={'userid': str(localemailaccount.user.id)}
|
||||||
))
|
))
|
||||||
return form(
|
return form(
|
||||||
{'objet': mailalias, 'objet_name': 'mailalias'},
|
{'objet': localemailaccount, 'objet_name': 'localemailaccount'},
|
||||||
'users/delete.html',
|
'users/delete.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_edit(User)
|
@can_edit(User)
|
||||||
def edit_mail(request, user_instance, **_kwargs):
|
def edit_email_settings(request, user_instance, **_kwargs):
|
||||||
""" Editer un compte mail"""
|
"""Edit the email settings of a user"""
|
||||||
mail = MailForm(
|
email_settings = EmailSettingsForm(
|
||||||
request.POST or None,
|
request.POST or None,
|
||||||
instance=user_instance,
|
instance=user_instance,
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
if mail.is_valid():
|
if email_settings.is_valid():
|
||||||
if mail.changed_data:
|
if email_settings.changed_data:
|
||||||
mail.save()
|
email_settings.save()
|
||||||
messages.success(request, "Option mail modifiée")
|
messages.success(request, "Email settings updated")
|
||||||
return redirect(reverse(
|
return redirect(reverse(
|
||||||
'users:profil',
|
'users:profil',
|
||||||
kwargs={'userid': str(user_instance.id)}
|
kwargs={'userid': str(user_instance.id)}
|
||||||
))
|
))
|
||||||
return form(
|
return form(
|
||||||
{'userform': mail, 'action_name': 'Editer les options mail'},
|
{'userform': email_settings,
|
||||||
|
'showCGU': False,
|
||||||
|
'action_name': 'Edit the email settings'},
|
||||||
'users/user.html',
|
'users/user.html',
|
||||||
request
|
request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@can_create(School)
|
@can_create(School)
|
||||||
def add_school(request):
|
def add_school(request):
|
||||||
|
@ -1002,10 +1012,11 @@ def profil(request, users, **_kwargs):
|
||||||
'white_list': whitelists,
|
'white_list': whitelists,
|
||||||
'user_solde': user_solde,
|
'user_solde': user_solde,
|
||||||
'solde_activated': Paiement.objects.filter(is_balance=True).exists(),
|
'solde_activated': Paiement.objects.filter(is_balance=True).exists(),
|
||||||
'allow_online_payment': allow_online_payment,
|
|
||||||
'asso_name': AssoOption.objects.first().name,
|
'asso_name': AssoOption.objects.first().name,
|
||||||
'alias_list': users.mailalias_set.all(),
|
'localemailaccount_list': users.local_email_accounts,
|
||||||
'mail_accounts': OptionalUser.objects.first().mail_accounts
|
'local_email_accounts_enabled': (
|
||||||
|
OptionalUser.objects.first().local_email_accounts_enabled
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue