8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-11-26 14:42:25 +00:00

Merge branch 'master' into klafyvel

This commit is contained in:
root 2017-10-26 10:46:45 +02:00
commit b54dbcee7a
10 changed files with 242 additions and 100 deletions

View file

@ -292,11 +292,12 @@ def decide_vlan_and_register_switch(nas, nas_type, port_number, mac_address):
if not port.room:
return (sw_name, u'Chambre inconnue', VLAN_NOK)
room_user = User.objects.filter(room=port.room)
room_user = User.objects.filter(Q(club__room=port.room) | Q(adherent__room=port.room))
if not room_user:
return (sw_name, u'Chambre non cotisante', VLAN_NOK)
elif not room_user.first().has_access():
return (sw_name, u'Chambre resident desactive', VLAN_NOK)
for user in room_user:
if not user.has_access():
return (sw_name, u'Chambre resident desactive', VLAN_NOK)
# else: user OK, on passe à la verif MAC
if port.radius == 'COMMON' or port.radius == 'STRICT':
@ -309,9 +310,12 @@ def decide_vlan_and_register_switch(nas, nas_type, port_number, mac_address):
elif not port.room:
return (sw_name, u'Chambre et machine inconnues', VLAN_NOK)
else:
room_user = User.objects.filter(room=Room.objects.filter(name=port.room))
if not room_user:
room_user = User.objects.filter(Q(club__room=port.room) | Q(adherent__room=port.room))
if not room_user:
return (sw_name, u'Machine et propriétaire de la chambre inconnus', VLAN_NOK)
elif room_user.count() > 1:
return (sw_name, u'Machine inconnue, il y a au moins 2 users dans la chambre/local -> ajout de mac automatique impossible', VLAN_NOK)
elif not room_user.first().has_access():
return (sw_name, u'Machine inconnue et adhérent non cotisant', VLAN_NOK)
else:

View file

@ -42,7 +42,7 @@ from django.db.models import Q
from cotisations.models import Cotisation, Facture, Paiement, Vente
from machines.models import Domain, Interface, Machine
from users.models import User, Ban, Whitelist
from users.models import Adherent, User, Ban, Whitelist
from preferences.models import Service
DT_NOW = timezone.now()
@ -238,3 +238,13 @@ class SortTable:
return request.reverse()
else:
return request
def remove_user_room(room):
""" Déménage de force l'ancien locataire de la chambre """
try:
user = Adherent.objects.get(room=room)
except Adherent.DoesNotExist:
return
user.room = None
user.save()

View file

@ -81,7 +81,7 @@ def search_result(search, type, request):
for i in aff:
if i == '0':
query_user_list = Q(room__name__icontains = search) | Q(pseudo__icontains = search) | Q(adherent__name__icontains = search) | Q(surname__icontains = search) & query1
query_user_list = Q(adherent__room__name__icontains = search) | Q(club__room__name__icontains = search) | Q(pseudo__icontains = search) | Q(adherent__name__icontains = search) | Q(surname__icontains = search) & query1
if request.user.has_perms(('cableur',)):
recherche['users_list'] = User.objects.filter(query_user_list).order_by('state', 'surname').distinct()
else :

View file

@ -44,13 +44,12 @@ class UserAdmin(admin.ModelAdmin):
list_display = (
'surname',
'pseudo',
'room',
'email',
'school',
'shell',
'state'
)
search_fields = ('surname', 'pseudo', 'room')
search_fields = ('surname', 'pseudo')
class LdapUserAdmin(admin.ModelAdmin):

View file

@ -41,7 +41,8 @@ from django.utils import timezone
from preferences.models import OptionalUser
from .models import User, ServiceUser, Right, School, ListRight, Whitelist
from .models import Ban, remove_user_room, Adherent, Club
from .models import Ban, Adherent, Club
from re2o.utils import remove_user_room
NOW = timezone.now()
@ -252,13 +253,13 @@ class MassArchiveForm(forms.Form):
utilisateurs dont la fin d'accès se situe dans le futur !")
class NewUserForm(ModelForm):
class AdherentForm(ModelForm):
"""Formulaire de base d'edition d'un user. Formulaire de base, utilisé
pour l'edition de self par self ou un cableur. On formate les champs
avec des label plus jolis"""
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(NewUserForm, self).__init__(*args, prefix=prefix, **kwargs)
super(AdherentForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields['name'].label = 'Prénom'
self.fields['surname'].label = 'Nom'
self.fields['school'].label = 'Établissement'
@ -291,18 +292,31 @@ class NewUserForm(ModelForm):
)
return telephone
force = forms.BooleanField(
label="Forcer le déménagement ?",
initial=False,
required=False
)
class NewClubForm(ModelForm):
def clean_force(self):
"""On supprime l'ancien user de la chambre si et seulement si la
case est cochée"""
if self.cleaned_data.get('force', False):
remove_user_room(self.cleaned_data.get('room'))
return
class ClubForm(ModelForm):
"""Formulaire de base d'edition d'un user. Formulaire de base, utilisé
pour l'edition de self par self ou un cableur. On formate les champs
avec des label plus jolis"""
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(NewClubForm, self).__init__(*args, prefix=prefix, **kwargs)
super(ClubForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields['surname'].label = 'Nom'
self.fields['school'].label = 'Établissement'
self.fields['comment'].label = 'Commentaire'
self.fields['room'].label = 'Chambre'
self.fields['room'].label = 'Local'
self.fields['room'].empty_label = "Pas de chambre"
self.fields['school'].empty_label = "Séléctionner un établissement"
@ -330,51 +344,13 @@ class NewClubForm(ModelForm):
return telephone
class BaseInfoForm(ModelForm):
"""Formulaire de base d'edition d'un user. Formulaire de base, utilisé
pour l'edition de self par self ou un cableur. On formate les champs
avec des label plus jolis"""
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(BaseInfoForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields['surname'].label = 'Nom'
self.fields['school'].label = 'Établissement'
self.fields['comment'].label = 'Commentaire'
self.fields['room'].label = 'Chambre'
self.fields['room'].empty_label = "Pas de chambre"
self.fields['school'].empty_label = "Séléctionner un établissement"
class Meta:
model = User
fields = [
'surname',
'pseudo',
'email',
'school',
'comment',
'room',
'telephone',
]
def clean_telephone(self):
"""Verifie que le tel est présent si 'option est validée
dans preferences"""
telephone = self.cleaned_data['telephone']
preferences, _created = OptionalUser.objects.get_or_create()
if not telephone and preferences.is_tel_mandatory:
raise forms.ValidationError(
"Un numéro de téléphone valide est requis"
)
return telephone
class EditInfoForm(BaseInfoForm):
class FullAdherentForm(AdherentForm):
"""Edition complète d'un user. Utilisé par admin,
permet d'editer normalement la chambre, ou le shell
Herite de la base"""
class Meta(BaseInfoForm.Meta):
class Meta(AdherentForm.Meta):
fields = [
'name',
'surname',
'pseudo',
'email',
@ -386,27 +362,21 @@ class EditInfoForm(BaseInfoForm):
]
class InfoForm(EditInfoForm):
""" Utile pour forcer un déménagement quand il y a déjà un user en place
Formuaire utilisé pour la creation initiale"""
force = forms.BooleanField(
label="Forcer le déménagement ?",
initial=False,
required=False
)
def clean_force(self):
"""On supprime l'ancien user de la chambre si et seulement si la
case est cochée"""
if self.cleaned_data.get('force', False):
remove_user_room(self.cleaned_data.get('room'))
return
class UserForm(InfoForm):
""" Model form general"""
class Meta(InfoForm.Meta):
fields = '__all__'
class FullClubForm(ClubForm):
"""Edition complète d'un user. Utilisé par admin,
permet d'editer normalement la chambre, ou le shell
Herite de la base"""
class Meta(ClubForm.Meta):
fields = [
'surname',
'pseudo',
'email',
'school',
'comment',
'room',
'shell',
'telephone',
]
class PasswordForm(ModelForm):

View file

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-24 23:54
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
def create_move_room(apps, schema_editor):
User = apps.get_model('users', 'User')
Adherent = apps.get_model('users', 'Adherent')
Club = apps.get_model('users', 'Club')
db_alias = schema_editor.connection.alias
users = Adherent.objects.using(db_alias).all()
clubs = Club.objects.using(db_alias).all()
for user in users:
user.room_adherent_id = user.room_id
user.save(using=db_alias)
for user in clubs:
user.room_club_id = user.room_id
user.save(using=db_alias)
def delete_move_room(apps, schema_editor):
User = apps.get_model('users', 'User')
Adherent = apps.get_model('users', 'Adherent')
Club = apps.get_model('users', 'Club')
db_alias = schema_editor.connection.alias
users = Adherent.objects.using(db_alias).all()
clubs = Club.objects.using(db_alias).all()
for user in users:
user.room_id = user.room_adherent_id
user.save(using=db_alias)
for user in clubs:
user.room_id = user.room_club_id
user.save(using=db_alias)
class Migration(migrations.Migration):
dependencies = [
('topologie', '0031_auto_20171015_2033'),
('users', '0057_auto_20171023_0301'),
]
operations = [
migrations.AddField(
model_name='adherent',
name='room_adherent',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='topologie.Room'),
),
migrations.AddField(
model_name='club',
name='room_club',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='topologie.Room'),
),
migrations.RunPython(create_move_room, delete_move_room),
migrations.RemoveField(
model_name='user',
name='room',
),
]

View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-25 16:54
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('users', '0058_auto_20171025_0154'),
]
operations = [
migrations.RenameField(
model_name='adherent',
old_name='room_adherent',
new_name='room',
),
migrations.RenameField(
model_name='club',
old_name='room_club',
new_name='room',
),
]

View file

@ -81,15 +81,6 @@ DT_NOW = timezone.now()
# Utilitaires généraux
def remove_user_room(room):
""" Déménage de force l'ancien locataire de la chambre """
try:
user = User.objects.get(room=room)
except User.DoesNotExist:
return
user.room = None
user.save()
def linux_user_check(login):
""" Validation du pseudo pour respecter les contraintes unix"""
@ -230,12 +221,6 @@ class User(AbstractBaseUser):
max_length=255,
blank=True
)
room = models.OneToOneField(
'topologie.Room',
on_delete=models.PROTECT,
blank=True,
null=True
)
pwd_ntlm = models.CharField(max_length=255)
state = models.IntegerField(choices=STATES, default=STATE_ACTIVE)
registered = models.DateTimeField(auto_now_add=True)
@ -256,6 +241,16 @@ class User(AbstractBaseUser):
else:
return ''
@cached_property
def room(self):
"""Alias vers room """
if self.is_class_adherent:
return self.adherent.room
elif self.is_class_club:
return self.club.room
else:
raise NotImplementedError("Type inconnu")
@cached_property
def class_name(self):
"""Renvoie si il s'agit d'un adhérent ou d'un club"""
@ -674,10 +669,34 @@ class User(AbstractBaseUser):
domain.interface_parent = interface_cible
domain.clean()
domain.save()
self.notif_auto_newmachine(interface_cible)
except Exception as error:
return False, error
return True, "Ok"
def notif_auto_newmachine(self, interface):
"""Notification mail lorsque une machine est automatiquement
ajoutée par le radius"""
template = loader.get_template('users/email_auto_newmachine')
assooptions, _created = AssoOption.objects.get_or_create()
general_options, _created = GeneralOption.objects.get_or_create()
context = Context({
'nom': self.get_full_name(),
'mac_address' : interface.mac_address,
'asso_name': assooptions.name,
'interface_name' : interface.domain,
'asso_email': assooptions.contact,
'pseudo': self.pseudo,
})
send_mail(
"Ajout automatique d'une machine / New machine autoregistered",
'',
general_options.email_from,
[self.email],
html_message=template.render(context)
)
return
def set_user_password(self, password):
""" A utiliser de préférence, set le password en hash courrant et
dans la version ntlm"""
@ -712,10 +731,22 @@ class User(AbstractBaseUser):
class Adherent(User):
name = models.CharField(max_length=255)
room = models.OneToOneField(
'topologie.Room',
on_delete=models.PROTECT,
blank=True,
null=True
)
pass
class Club(User):
room = models.ForeignKey(
'topologie.Room',
on_delete=models.PROTECT,
blank=True,
null=True
)
pass

View file

@ -0,0 +1,27 @@
<p>Bonjour {{nom}} </p>
<p>Une nouvelle machine a automatiquement été inscrite sur votre compte.</p>
<p>Si vous êtes à l'origine de la connexion de cet appareil en filaire ou wifi, ne tenez pas compte de cette notification</p>
<p>La nouvelle machine possède l'adresse mac {{ mac_address }}, et s'est vu assigner le nom suivant : {{ interface_name }}</p>
<p>Vous pouvez à tout moment modifier ces informations sur votre compte en ligne</p>
<p>Si vous n'êtes pas à l'origine de cette connexion, merci de le signaler rapidement à {{asso_email}}</p>
<p>À bientôt,<br>
L'équipe de {{asso_name}}.</p>
<p>---</p>
<p>A new device has been automatically added on your account.</p>
<p>If you connected a new device recently, please don't take this mail into account<p>
<p>The new device has this mac address : {{ mac_address }}, and this name : {{ interface_name }}</p>
<p>Please contact us if you didn't connect a new device with this mail address {{asso_email}}.</p>
<p>Regards,<br>
The {{asso_name}} team.</p>

View file

@ -55,10 +55,10 @@ from users.serializers import MailSerializer
from users.models import User, Right, Ban, Whitelist, School, ListRight
from users.models import Request, ServiceUser, Adherent, Club
from users.forms import DelRightForm, BanForm, WhitelistForm, DelSchoolForm
from users.forms import DelListRightForm, NewListRightForm
from users.forms import InfoForm, BaseInfoForm, StateForm
from users.forms import DelListRightForm, NewListRightForm, FullAdherentForm
from users.forms import StateForm, FullClubForm
from users.forms import RightForm, SchoolForm, EditServiceUserForm
from users.forms import ServiceUserForm, ListRightForm, NewUserForm, NewClubForm
from users.forms import ServiceUserForm, ListRightForm, AdherentForm, ClubForm
from users.forms import MassArchiveForm, PassForm, ResetPasswordForm
from cotisations.models import Facture
from machines.models import Machine
@ -85,7 +85,7 @@ def password_change_action(u_form, user, request, req=False):
def new_user(request):
""" Vue de création d'un nouvel utilisateur,
envoie un mail pour le mot de passe"""
user = NewUserForm(request.POST or None)
user = AdherentForm(request.POST or None)
if user.is_valid():
user = user.save(commit=False)
with transaction.atomic(), reversion.create_revision():
@ -104,7 +104,7 @@ def new_user(request):
def new_club(request):
""" Vue de création d'un nouveau club,
envoie un mail pour le mot de passe"""
club = NewClubForm(request.POST or None)
club = ClubForm(request.POST or None)
if club.is_valid():
club = club.save(commit=False)
with transaction.atomic(), reversion.create_revision():
@ -118,6 +118,24 @@ def new_club(request):
return form({'userform': club}, 'users/user.html', request)
def select_user_edit_form(request, user):
"""Fonction de choix du bon formulaire, en fonction de:
- droit
- type d'object
"""
if not request.user.has_perms(('cableur',)):
if user.is_class_adherent:
user = AdherentForm(request.POST or None, instance=user.adherent)
elif user.is_class_club:
user = ClubForm(request.POST or None, instance=user.club)
else:
if user.is_class_adherent:
user = FullAdherentForm(request.POST or None, instance=user.adherent)
elif user.is_class_club:
user = FullClubForm(request.POST or None, instance=user.club)
return user
@login_required
def edit_info(request, userid):
""" Edite un utilisateur à partir de son id,
@ -132,10 +150,7 @@ def edit_info(request, userid):
messages.error(request, "Vous ne pouvez pas modifier un autre\
user que vous sans droit cableur")
return redirect("/users/profil/" + str(request.user.id))
if not request.user.has_perms(('cableur',)):
user = BaseInfoForm(request.POST or None, instance=user)
else:
user = InfoForm(request.POST or None, instance=user)
user = select_user_edit_form(request, user)
if user.is_valid():
with transaction.atomic(), reversion.create_revision():
user.save()