views.py 35.4 KB
Newer Older
Gabriel Detraz's avatar
Gabriel Detraz committed
1
# -*- mode: python; coding: utf-8 -*-
lhark's avatar
lhark committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017  Gabriel Détraz
# Copyright © 2017  Goulven Kermarec
# Copyright © 2017  Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

chirac's avatar
chirac committed
24
# App de gestion des users pour re2o
Dalahro's avatar
Dalahro committed
25
# Goulven Kermarec, Gabriel Détraz, Lemesle Augustin
chirac's avatar
chirac committed
26
# Gplv2
27
28
29
30
31
32
33
34
35
"""
Module des views.

On définit les vues pour l'ajout, l'edition des users : infos personnelles,
mot de passe, etc

Permet aussi l'ajout, edition et suppression des droits, des bannissements,
des whitelist, des services users et des écoles
"""
36
37
38

from __future__ import unicode_literals

39
from django.urls import reverse
40
from django.shortcuts import get_object_or_404, render, redirect
41
from django.contrib import messages
42
from django.contrib.auth.decorators import login_required, permission_required
43
from django.db.models import ProtectedError, Count, Max
44
from django.utils import timezone
45
from django.db import transaction
46
from django.http import HttpResponse
47
from django.http import HttpResponseRedirect
48
49
50
from django.views.decorators.csrf import csrf_exempt

from rest_framework.renderers import JSONRenderer
Maël Kervella's avatar
Maël Kervella committed
51
from reversion import revisions as reversion
52

53
from cotisations.models import Facture, Paiement
Maël Kervella's avatar
Maël Kervella committed
54
from machines.models import Machine
Gabriel Detraz's avatar
Gabriel Detraz committed
55
from preferences.models import OptionalUser, GeneralOption, AssoOption
Maël Kervella's avatar
Maël Kervella committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
from re2o.views import form
from re2o.utils import (
    all_has_access,
    SortTable,
    re2o_paginator
)
from re2o.acl import (
    can_create,
    can_edit,
    can_delete_set,
    can_delete,
    can_view,
    can_view_all,
    can_change
)
71
from cotisations.utils import find_payment_method
lhark's avatar
lhark committed
72

Maël Kervella's avatar
Maël Kervella committed
73
74
from .serializers import MailingSerializer, MailingMemberSerializer
from .models import (
75
76
77
78
79
80
81
82
    User,
    Ban,
    Whitelist,
    School,
    ListRight,
    Request,
    ServiceUser,
    Adherent,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
83
    Club,
84
    ListShell,
85
    EMailAddress,
86
)
Maël Kervella's avatar
Maël Kervella committed
87
from .forms import (
88
89
    BanForm,
    WhitelistForm,
90
    EMailAddressForm,
91
    EmailSettingsForm,
92
93
94
95
96
    DelSchoolForm,
    DelListRightForm,
    NewListRightForm,
    StateForm,
    SchoolForm,
97
    ShellForm,
98
99
100
101
102
103
104
105
    EditServiceUserForm,
    ServiceUserForm,
    ListRightForm,
    AdherentForm,
    ClubForm,
    MassArchiveForm,
    PassForm,
    ResetPasswordForm,
106
107
    ClubAdminandMembersForm,
    GroupForm
108
)
109

Maël Kervella's avatar
Maël Kervella committed
110

111
@can_create(Adherent)
chirac's avatar
chirac committed
112
def new_user(request):
113
114
    """ Vue de création d'un nouvel utilisateur,
    envoie un mail pour le mot de passe"""
115
    user = AdherentForm(request.POST or None, user=request.user)
116
117
    GTU_sum_up = GeneralOption.get_cached_value('GTU_sum_up')
    GTU = GeneralOption.get_cached_value('GTU')
118
    if user.is_valid():
119
        user = user.save()
120
        user.reset_passwd_mail(request)
121
122
        messages.success(request, "L'utilisateur %s a été crée, un mail\
        pour l'initialisation du mot de passe a été envoyé" % user.pseudo)
123
124
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
125
126
127
128
129
130
131
132
133
134
135
136
137
            kwargs={'userid': str(user.id)}
        ))
    return form(
        {
            'userform': user,
            'GTU_sum_up': GTU_sum_up,
            'GTU': GTU,
            'showCGU': True,
            'action_name': 'Créer un utilisateur'
        },
        'users/user.html',
        request
    )
138

139

140
@login_required
141
@can_create(Club)
142
143
144
def new_club(request):
    """ Vue de création d'un nouveau club,
    envoie un mail pour le mot de passe"""
145
    club = ClubForm(request.POST or None, user=request.user)
146
147
    if club.is_valid():
        club = club.save(commit=False)
148
        club.save()
149
150
151
        club.reset_passwd_mail(request)
        messages.success(request, "L'utilisateur %s a été crée, un mail\
        pour l'initialisation du mot de passe a été envoyé" % club.pseudo)
152
153
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
154
155
156
157
158
159
160
            kwargs={'userid': str(club.id)}
        ))
    return form(
        {'userform': club, 'showCGU': False, 'action_name': 'Créer un club'},
        'users/user.html',
        request
    )
161
162


163
@login_required
164
@can_edit(Club)
165
def edit_club_admin_members(request, club_instance, **_kwargs):
166
167
    """Vue d'edition de la liste des users administrateurs et
    membres d'un club"""
Maël Kervella's avatar
Maël Kervella committed
168
169
170
171
    club = ClubAdminandMembersForm(
        request.POST or None,
        instance=club_instance
    )
172
    if club.is_valid():
173
174
175
        if club.changed_data:
            club.save()
            messages.success(request, "Le club a bien été modifié")
176
177
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
178
179
180
181
182
183
184
185
186
187
188
            kwargs={'userid': str(club_instance.id)}
        ))
    return form(
        {
            'userform': club,
            'showCGU': False,
            'action_name': 'Editer les admin et membres'
        },
        'users/user.html',
        request
    )
189
190


chirac's avatar
chirac committed
191
@login_required
192
@can_edit(User)
193
def edit_info(request, user, userid):
194
195
196
    """ Edite un utilisateur à partir de son id,
    si l'id est différent de request.user, vérifie la
    possession du droit cableur """
197
    if user.is_class_adherent:
Maël Kervella's avatar
Maël Kervella committed
198
        user_form = AdherentForm(
199
200
201
202
            request.POST or None,
            instance=user.adherent,
            user=request.user
        )
Maël Kervella's avatar
Maël Kervella committed
203
204
    else:
        user_form = ClubForm(
205
206
207
208
            request.POST or None,
            instance=user.club,
            user=request.user
        )
Maël Kervella's avatar
Maël Kervella committed
209
210
211
    if user_form.is_valid():
        if user_form.changed_data:
            user_form.save()
212
            messages.success(request, "L'user a bien été modifié")
213
214
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
215
216
217
            kwargs={'userid': str(userid)}
        ))
    return form(
Maël Kervella's avatar
Maël Kervella committed
218
        {'userform': user_form, 'action_name': "Editer l'utilisateur"},
Maël Kervella's avatar
Maël Kervella committed
219
220
221
        'users/user.html',
        request
    )
222

223

chirac's avatar
chirac committed
224
@login_required
225
@can_edit(User, 'state')
226
def state(request, user, userid):
chirac's avatar
chirac committed
227
    """ Change the state (active/unactive/archived) of a user"""
Maël Kervella's avatar
Maël Kervella committed
228
229
230
231
    state_form = StateForm(request.POST or None, instance=user)
    if state_form.is_valid():
        if state_form.changed_data:
            state_form.save()
232
            messages.success(request, "Etat changé avec succès")
233
234
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
235
236
237
            kwargs={'userid': str(userid)}
        ))
    return form(
Maël Kervella's avatar
Maël Kervella committed
238
        {'userform': state_form, 'action_name': "Editer l'état"},
Maël Kervella's avatar
Maël Kervella committed
239
240
241
        'users/user.html',
        request
    )
242

243

244
@login_required
245
@can_edit(User, 'groups')
246
def groups(request, user, userid):
Maël Kervella's avatar
Maël Kervella committed
247
    """ View to edit the groups of a user """
248
249
    group_form = GroupForm(request.POST or None,
                           instance=user, user=request.user)
Maël Kervella's avatar
Maël Kervella committed
250
251
252
    if group_form.is_valid():
        if group_form.changed_data:
            group_form.save()
253
            messages.success(request, "Groupes changés avec succès")
254
255
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
256
            kwargs={'userid': str(userid)}
257
        ))
Maël Kervella's avatar
Maël Kervella committed
258
    return form(
Maël Kervella's avatar
Maël Kervella committed
259
        {'userform': group_form, 'action_name': 'Editer les groupes'},
Maël Kervella's avatar
Maël Kervella committed
260
261
262
        'users/user.html',
        request
    )
263
264


chirac's avatar
chirac committed
265
@login_required
266
@can_edit(User, 'password')
267
def password(request, user, userid):
chirac's avatar
chirac committed
268
269
270
    """ Reinitialisation d'un mot de passe à partir de l'userid,
    pour self par défaut, pour tous sans droit si droit cableur,
    pour tous si droit bureau """
271
    u_form = PassForm(request.POST or None, instance=user, user=request.user)
272
    if u_form.is_valid():
273
274
275
        if u_form.changed_data:
            u_form.save()
            messages.success(request, "Le mot de passe a changé")
276
        return redirect(reverse(
Maël Kervella's avatar
Maël Kervella committed
277
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
278
            kwargs={'userid': str(userid)}
279
        ))
Maël Kervella's avatar
Maël Kervella committed
280
281
282
283
284
    return form(
        {'userform': u_form, 'action_name': 'Changer le mot de passe'},
        'users/user.html',
        request
    )
chirac's avatar
chirac committed
285

286

287
@login_required
288
@can_edit(User, 'groups')
289
def del_group(request, user, listrightid, **_kwargs):
Maël Kervella's avatar
Maël Kervella committed
290
    """ View used to delete a group """
291
292
293
    user.groups.remove(ListRight.objects.get(id=listrightid))
    user.save()
    messages.success(request, "Droit supprimé à %s" % user)
294
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
295
296


Hugo LEVY-FALK's avatar
Hugo LEVY-FALK committed
297
@login_required
Hugo LEVY-FALK's avatar
ACL    
Hugo LEVY-FALK committed
298
@can_edit(User, 'is_superuser')
Hugo LEVY-FALK's avatar
Hugo LEVY-FALK committed
299
300
301
302
303
304
305
306
def del_superuser(request, user, **_kwargs):
    """Remove the superuser right of an user."""
    user.is_superuser = False
    user.save()
    messages.success(request, "%s n'est plus superuser" % user)
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))


307
@login_required
308
@can_create(ServiceUser)
309
310
311
312
def new_serviceuser(request):
    """ Vue de création d'un nouvel utilisateur service"""
    user = ServiceUserForm(request.POST or None)
    if user.is_valid():
313
        user.save()
314
315
        messages.success(
            request,
316
            "L'utilisateur a été crée"
317
        )
318
        return redirect(reverse('users:index-serviceusers'))
Maël Kervella's avatar
Maël Kervella committed
319
320
321
322
323
    return form(
        {'userform': user, 'action_name': 'Créer un serviceuser'},
        'users/user.html',
        request
    )
324

325

326
@login_required
327
@can_edit(ServiceUser)
328
def edit_serviceuser(request, serviceuser, **_kwargs):
329
    """ Edit a ServiceUser """
Maël Kervella's avatar
Maël Kervella committed
330
331
332
333
    serviceuser = EditServiceUserForm(
        request.POST or None,
        instance=serviceuser
    )
Gabriel Detraz's avatar
Gabriel Detraz committed
334
335
    if serviceuser.is_valid():
        if serviceuser.changed_data:
336
            serviceuser.save()
337
        messages.success(request, "L'user a bien été modifié")
338
        return redirect(reverse('users:index-serviceusers'))
Maël Kervella's avatar
Maël Kervella committed
339
340
341
342
343
    return form(
        {'userform': serviceuser, 'action_name': 'Editer un serviceuser'},
        'users/user.html',
        request
    )
344

345

346
@login_required
347
@can_delete(ServiceUser)
348
def del_serviceuser(request, serviceuser, **_kwargs):
349
    """Suppression d'un ou plusieurs serviceusers"""
350
    if request.method == "POST":
Gabriel Detraz's avatar
Gabriel Detraz committed
351
        serviceuser.delete()
352
        messages.success(request, "L'user a été détruit")
353
        return redirect(reverse('users:index-serviceusers'))
354
    return form(
Gabriel Detraz's avatar
Gabriel Detraz committed
355
        {'objet': serviceuser, 'objet_name': 'serviceuser'},
356
357
358
359
        'users/delete.html',
        request
    )

360

chirac's avatar
chirac committed
361
@login_required
362
363
364
@can_create(Ban)
@can_edit(User)
def add_ban(request, user, userid):
365
366
    """ Ajouter un banissement, nécessite au moins le droit bofh
    (a fortiori bureau)
chirac's avatar
chirac committed
367
    Syntaxe : JJ/MM/AAAA , heure optionnelle, prend effet immédiatement"""
368
369
370
    ban_instance = Ban(user=user)
    ban = BanForm(request.POST or None, instance=ban_instance)
    if ban.is_valid():
Maël Kervella's avatar
Maël Kervella committed
371
        ban.save()
372
        messages.success(request, "Bannissement ajouté")
373
374
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
375
            kwargs={'userid': str(userid)}
376
        ))
377
    if user.is_ban():
378
379
380
381
        messages.error(
            request,
            "Attention, cet utilisateur a deja un bannissement actif"
        )
Maël Kervella's avatar
Maël Kervella committed
382
383
384
385
386
387
    return form(
        {'userform': ban, 'action_name': 'Ajouter un ban'},
        'users/user.html',
        request
    )

388

chirac's avatar
chirac committed
389
@login_required
390
@can_edit(Ban)
391
def edit_ban(request, ban_instance, **_kwargs):
392
393
    """ Editer un bannissement, nécessite au moins le droit bofh
    (a fortiori bureau)
chirac's avatar
chirac committed
394
    Syntaxe : JJ/MM/AAAA , heure optionnelle, prend effet immédiatement"""
395
396
    ban = BanForm(request.POST or None, instance=ban_instance)
    if ban.is_valid():
397
398
399
        if ban.changed_data:
            ban.save()
            messages.success(request, "Bannissement modifié")
400
        return redirect(reverse('users:index'))
Maël Kervella's avatar
Maël Kervella committed
401
402
403
404
405
    return form(
        {'userform': ban, 'action_name': 'Editer un ban'},
        'users/user.html',
        request
    )
406

407

408
409
410
@login_required
@can_delete(Ban)
def del_ban(request, ban, **_kwargs):
411
412
413
414
415
416
417
418
419
420
421
422
423
    """ Supprime un banissement"""
    if request.method == "POST":
        ban.delete()
        messages.success(request, "Le banissement a été supprimé")
        return redirect(reverse(
            'users:profil',
            kwargs={'userid': str(ban.user.id)}
        ))
    return form(
        {'objet': ban, 'objet_name': 'ban'},
        'users/delete.html',
        request
    )
424

425

chirac's avatar
chirac committed
426
@login_required
427
428
429
@can_create(Whitelist)
@can_edit(User)
def add_whitelist(request, user, userid):
430
431
432
433
    """ Accorder un accès gracieux, temporaire ou permanent.
    Need droit cableur
    Syntaxe : JJ/MM/AAAA , heure optionnelle, prend effet immédiatement,
    raison obligatoire"""
chirac's avatar
chirac committed
434
    whitelist_instance = Whitelist(user=user)
435
436
437
438
    whitelist = WhitelistForm(
        request.POST or None,
        instance=whitelist_instance
    )
chirac's avatar
chirac committed
439
    if whitelist.is_valid():
440
        whitelist.save()
chirac's avatar
chirac committed
441
        messages.success(request, "Accès à titre gracieux accordé")
442
443
        return redirect(reverse(
            'users:profil',
Maël Kervella's avatar
Maël Kervella committed
444
445
            kwargs={'userid': str(userid)}
        ))
446
    if user.is_whitelisted():
447
448
449
450
        messages.error(
            request,
            "Attention, cet utilisateur a deja un accès gracieux actif"
        )
Maël Kervella's avatar
Maël Kervella committed
451
452
453
454
455
    return form(
        {'userform': whitelist, 'action_name': 'Ajouter une whitelist'},
        'users/user.html',
        request
    )
chirac's avatar
chirac committed
456

457

chirac's avatar
chirac committed
458
@login_required
459
@can_edit(Whitelist)
460
def edit_whitelist(request, whitelist_instance, **_kwargs):
461
462
463
464
465
466
467
468
    """ Editer un accès gracieux, temporaire ou permanent.
    Need droit cableur
    Syntaxe : JJ/MM/AAAA , heure optionnelle, prend effet immédiatement,
    raison obligatoire"""
    whitelist = WhitelistForm(
        request.POST or None,
        instance=whitelist_instance
    )
chirac's avatar
chirac committed
469
    if whitelist.is_valid():
470
471
472
        if whitelist.changed_data:
            whitelist.save()
            messages.success(request, "Whitelist modifiée")
473
        return redirect(reverse('users:index'))
Maël Kervella's avatar
Maël Kervella committed
474
475
476
477
478
    return form(
        {'userform': whitelist, 'action_name': 'Editer une whitelist'},
        'users/user.html',
        request
    )
chirac's avatar
chirac committed
479

480

481
482
483
@login_required
@can_delete(Whitelist)
def del_whitelist(request, whitelist, **_kwargs):
484
485
486
487
488
489
490
491
492
493
494
495
496
497
    """ Supprime un acces gracieux"""
    if request.method == "POST":
        whitelist.delete()
        messages.success(request, "L'accés gracieux a été supprimé")
        return redirect(reverse(
            'users:profil',
            kwargs={'userid': str(whitelist.user.id)}
        ))
    return form(
        {'objet': whitelist, 'objet_name': 'whitelist'},
        'users/delete.html',
        request
    )

498

499
@login_required
500
@can_create(EMailAddress)
501
@can_edit(User)
502
def add_emailaddress(request, user, userid):
503
    """ Create a new local email account"""
504
505
    emailaddress_instance = EMailAddress(user=user)
    emailaddress = EMailAddressForm(
506
        request.POST or None,
507
        instance=emailaddress_instance
508
    )
509
510
    if emailaddress.is_valid():
        emailaddress.save()
511
        messages.success(request, "Local email account created")
512
513
514
515
516
        return redirect(reverse(
            'users:profil',
            kwargs={'userid': str(userid)}
        ))
    return form(
517
        {'userform': emailaddress,
518
519
         'showCGU': False,
         'action_name': 'Add a local email account'},
520
521
522
523
        'users/user.html',
        request
    )

524

525
@login_required
526
527
@can_edit(EMailAddress)
def edit_emailaddress(request, emailaddress_instance, **_kwargs):
528
    """ Edit a local email account"""
529
    emailaddress = EMailAddressForm(
530
        request.POST or None,
531
        instance=emailaddress_instance
532
    )
533
534
535
    if emailaddress.is_valid():
        if emailaddress.changed_data:
            emailaddress.save()
536
            messages.success(request, "Local email account modified")
chirac's avatar
chirac committed
537
538
        return redirect(reverse(
            'users:profil',
539
            kwargs={'userid': str(emailaddress_instance.user.id)}
chirac's avatar
chirac committed
540
        ))
541
    return form(
542
        {'userform': emailaddress,
543
544
         'showCGU': False,
         'action_name': 'Edit a local email account'},
545
546
547
548
        'users/user.html',
        request
    )

549

550
@login_required
551
552
@can_delete(EMailAddress)
def del_emailaddress(request, emailaddress, **_kwargs):
553
554
    """Delete a local email account"""
    if request.method == "POST":
555
        emailaddress.delete()
556
557
558
        messages.success(request, "Local email account deleted")
        return redirect(reverse(
            'users:profil',
559
            kwargs={'userid': str(emailaddress.user.id)}
560
561
            ))
    return form(
562
        {'objet': emailaddress, 'objet_name': 'emailaddress'},
563
564
565
566
        'users/delete.html',
        request
    )

567

568
@login_required
chirac's avatar
chirac committed
569
@can_edit(User)
570
571
572
def edit_email_settings(request, user_instance, **_kwargs):
    """Edit the email settings of a user"""
    email_settings = EmailSettingsForm(
573
        request.POST or None,
574
575
        instance=user_instance,
        user=request.user
576
    )
577
578
579
580
    if email_settings.is_valid():
        if email_settings.changed_data:
            email_settings.save()
            messages.success(request, "Email settings updated")
581
582
583
584
        return redirect(reverse(
            'users:profil',
            kwargs={'userid': str(user_instance.id)}
            ))
585
    return form(
586
587
588
        {'userform': email_settings,
         'showCGU': False,
         'action_name': 'Edit the email settings'},
589
590
591
592
        'users/user.html',
        request
    )

593

chirac's avatar
chirac committed
594
@login_required
595
@can_create(School)
chirac's avatar
chirac committed
596
def add_school(request):
597
598
    """ Ajouter un établissement d'enseignement à la base de donnée,
    need cableur"""
chirac's avatar
chirac committed
599
600
    school = SchoolForm(request.POST or None)
    if school.is_valid():
601
        school.save()
chirac's avatar
chirac committed
602
        messages.success(request, "L'établissement a été ajouté")
603
        return redirect(reverse('users:index-school'))
Maël Kervella's avatar
Maël Kervella committed
604
605
606
607
608
    return form(
        {'userform': school, 'action_name': 'Ajouter'},
        'users/user.html',
        request
    )
chirac's avatar
chirac committed
609

610

chirac's avatar
chirac committed
611
@login_required
612
@can_edit(School)
613
def edit_school(request, school_instance, **_kwargs):
614
615
    """ Editer un établissement d'enseignement à partir du schoolid dans
    la base de donnée, need cableur"""
616
617
    school = SchoolForm(request.POST or None, instance=school_instance)
    if school.is_valid():
618
619
620
        if school.changed_data:
            school.save()
            messages.success(request, "Établissement modifié")
621
        return redirect(reverse('users:index-school'))
Maël Kervella's avatar
Maël Kervella committed
622
623
624
625
626
    return form(
        {'userform': school, 'action_name': 'Editer'},
        'users/user.html',
        request
    )
627

628

chirac's avatar
chirac committed
629
@login_required
630
@can_delete_set(School)
631
def del_school(request, instances):
632
633
634
635
    """ Supprimer un établissement d'enseignement à la base de donnée,
    need cableur
    Objet protégé, possible seulement si aucun user n'est affecté à
    l'établissement """
636
    school = DelSchoolForm(request.POST or None, instances=instances)
chirac's avatar
chirac committed
637
638
639
640
    if school.is_valid():
        school_dels = school.cleaned_data['schools']
        for school_del in school_dels:
            try:
641
                school_del.delete()
chirac's avatar
chirac committed
642
643
                messages.success(request, "L'établissement a été supprimé")
            except ProtectedError:
644
645
646
                messages.error(
                    request,
                    "L'établissement %s est affecté à au moins un user, \
lhark's avatar
lhark committed
647
                        vous ne pouvez pas le supprimer" % school_del)
648
        return redirect(reverse('users:index-school'))
Maël Kervella's avatar
Maël Kervella committed
649
650
651
652
653
    return form(
        {'userform': school, 'action_name': 'Supprimer'},
        'users/user.html',
        request
    )
chirac's avatar
chirac committed
654

655

656
657
658
@login_required
@can_create(ListShell)
def add_shell(request):
Gabriel Detraz's avatar
Gabriel Detraz committed
659
    """ Ajouter un shell à la base de donnée"""
660
661
    shell = ShellForm(request.POST or None)
    if shell.is_valid():
662
        shell.save()
663
664
        messages.success(request, "Le shell a été ajouté")
        return redirect(reverse('users:index-shell'))
Maël Kervella's avatar
Maël Kervella committed
665
666
667
668
669
    return form(
        {'userform': shell, 'action_name': 'Ajouter'},
        'users/user.html',
        request
    )
670
671
672
673


@login_required
@can_edit(ListShell)
674
def edit_shell(request, shell_instance, **_kwargs):
Gabriel Detraz's avatar
Gabriel Detraz committed
675
    """ Editer un shell à partir du listshellid"""
676
677
    shell = ShellForm(request.POST or None, instance=shell_instance)
    if shell.is_valid():
678
679
680
        if shell.changed_data:
            shell.save()
            messages.success(request, "Le shell a été modifié")
681
        return redirect(reverse('users:index-shell'))
Maël Kervella's avatar
Maël Kervella committed
682
683
684
685
686
    return form(
        {'userform': shell, 'action_name': 'Editer'},
        'users/user.html',
        request
    )
687
688
689
690


@login_required
@can_delete(ListShell)
691
def del_shell(request, shell, **_kwargs):
692
693
    """Destruction d'un shell"""
    if request.method == "POST":
694
        shell.delete()
695
696
697
698
699
700
701
702
703
        messages.success(request, "Le shell a été détruit")
        return redirect(reverse('users:index-shell'))
    return form(
        {'objet': shell, 'objet_name': 'shell'},
        'users/delete.html',
        request
    )


704
@login_required
705
@can_create(ListRight)
706
def add_listright(request):
chirac's avatar
chirac committed
707
708
    """ Ajouter un droit/groupe, nécessite droit bureau.
    Obligation de fournir un gid pour la synchro ldap, unique """
709
710
    listright = NewListRightForm(request.POST or None)
    if listright.is_valid():
711
        listright.save()
712
        messages.success(request, "Le droit/groupe a été ajouté")
713
        return redirect(reverse('users:index-listright'))
Maël Kervella's avatar
Maël Kervella committed
714
715
716
717
718
    return form(
        {'userform': listright, 'action_name': 'Ajouter'},
        'users/user.html',
        request
    )
719

720

721
@login_required
722
@can_edit(ListRight)
723
def edit_listright(request, listright_instance, **_kwargs):
724
725
726
727
728
729
    """ Editer un groupe/droit, necessite droit bureau,
    à partir du listright id """
    listright = ListRightForm(
        request.POST or None,
        instance=listright_instance
    )
730
    if listright.is_valid():
731
732
733
        if listright.changed_data:
            listright.save()
            messages.success(request, "Droit modifié")
734
        return redirect(reverse('users:index-listright'))
Maël Kervella's avatar
Maël Kervella committed
735
736
737
738
739
    return form(
        {'userform': listright, 'action_name': 'Editer'},
        'users/user.html',
        request
    )
740

741

742
@login_required
743
@can_delete_set(ListRight)
744
def del_listright(request, instances):
745
746
    """ Supprimer un ou plusieurs groupe, possible si il est vide, need droit
    bureau """
747
    listright = DelListRightForm(request.POST or None, instances=instances)
748
749
750
751
    if listright.is_valid():
        listright_dels = listright.cleaned_data['listrights']
        for listright_del in listright_dels:
            try:
752
                listright_del.delete()
753
754
755
756
                messages.success(request, "Le droit/groupe a été supprimé")
            except ProtectedError:
                messages.error(
                    request,
757
                    "Le groupe %s est affecté à au moins un user, \
758
                        vous ne pouvez pas le supprimer" % listright_del)
759
        return redirect(reverse('users:index-listright'))
Maël Kervella's avatar
Maël Kervella committed
760
761
762
763
764
    return form(
        {'userform': listright, 'action_name': 'Supprimer'},
        'users/user.html',
        request
    )
765

766

767
@login_required
768
769
@can_view_all(User)
@can_change(User, 'state')
770
771
772
773
774
775
def mass_archive(request):
    """ Permet l'archivage massif"""
    to_archive_date = MassArchiveForm(request.POST or None)
    to_archive_list = []
    if to_archive_date.is_valid():
        date = to_archive_date.cleaned_data['date']
776
777
778
779
        to_archive_list = [user for user in
                           User.objects.exclude(state=User.STATE_ARCHIVE)
                           if not user.end_access()
                           or user.end_access() < date]
780
781
782
        if "valider" in request.POST:
            for user in to_archive_list:
                with transaction.atomic(), reversion.create_revision():
783
                    user.archive()
784
785
                    user.save()
                    reversion.set_comment("Archivage")
786
787
788
            messages.success(request, "%s users ont été archivés" % len(
                to_archive_list
            ))
789
            return redirect(reverse('users:index'))
790
791
792
793
794
795
    return form(
        {'userform': to_archive_date, 'to_archive_list': to_archive_list},
        'users/mass_archive.html',
        request
    )

796

chirac's avatar
chirac committed
797
@login_required
798
@can_view_all(Adherent)
chirac's avatar
chirac committed
799
def index(request):
800
    """ Affiche l'ensemble des adherents, need droit cableur """
801
    pagination_number = GeneralOption.get_cached_value('pagination_number')
802
    users_list = Adherent.objects.select_related('room')
803
804
805
806
807
808
    users_list = SortTable.sort(
        users_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX
    )
809
    users_list = re2o_paginator(request, users_list, pagination_number)
810
    return render(request, 'users/index.html', {'users_list': users_list})
root's avatar
root committed
811

812

813
@login_required
814
@can_view_all(Club)
815
816
def index_clubs(request):
    """ Affiche l'ensemble des clubs, need droit cableur """
817
    pagination_number = GeneralOption.get_cached_value('pagination_number')
818
    clubs_list = Club.objects.select_related('room')
819
820
821
822
823
824
    clubs_list = SortTable.sort(
        clubs_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX
    )
825
    clubs_list = re2o_paginator(request, clubs_list, pagination_number)
Maël Kervella's avatar
Maël Kervella committed
826
827
828
829
830
    return render(
        request,
        'users/index_clubs.html',
        {'clubs_list': clubs_list}
    )
831
832


chirac's avatar
chirac committed
833
@login_required
834
@can_view_all(Ban)
835
def index_ban(request):
chirac's avatar
chirac committed
836
    """ Affiche l'ensemble des ban, need droit cableur """
837
    pagination_number = GeneralOption.get_cached_value('pagination_number')
838
839
840
841
842
843
844
    ban_list = Ban.objects.select_related('user')
    ban_list = SortTable.sort(
        ban_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX_BAN
    )
845
    ban_list = re2o_paginator(request, ban_list, pagination_number)
846
    return render(request, 'users/index_ban.html', {'ban_list': ban_list})
847

848

chirac's avatar
chirac committed
849
@login_required
850
@can_view_all(Whitelist)
851
def index_white(request):
chirac's avatar
chirac committed
852
    """ Affiche l'ensemble des whitelist, need droit cableur """
853
    pagination_number = GeneralOption.get_cached_value('pagination_number')
854
855
856
857
858
859
860
    white_list = Whitelist.objects.select_related('user')
    white_list = SortTable.sort(
        white_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX_BAN
    )
861
    white_list = re2o_paginator(request, white_list, pagination_number)
862
863
864
865
866
867
    return render(
        request,
        'users/index_whitelist.html',
        {'white_list': white_list}
    )

868

chirac's avatar
chirac committed
869
@login_required
870
@can_view_all(School)
871
def index_school(request):
872
    """ Affiche l'ensemble des établissement"""
873
    school_list = School.objects.order_by('name')
874
875
876
877
878
879
880
    pagination_number = GeneralOption.get_cached_value('pagination_number')
    school_list = SortTable.sort(
        school_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX_SCHOOL
    )
881
    school_list = re2o_paginator(request, school_list, pagination_number)
882
883
884
885
886
887
    return render(
        request,
        'users/index_schools.html',
        {'school_list': school_list}
    )

888

889
890
891
892
893
894
895
896
897
898
899
900
@login_required
@can_view_all(ListShell)
def index_shell(request):
    """ Affiche l'ensemble des shells"""
    shell_list = ListShell.objects.order_by('shell')
    return render(
        request,
        'users/index_shell.html',
        {'shell_list': shell_list}
    )


901
@login_required
902
@can_view_all(ListRight)
903
def index_listright(request):
904
    """ Affiche l'ensemble des droits"""
905
906
907
908
909
    rights = {}
    for right in (ListRight.objects
                  .order_by('name')
                  .prefetch_related('permissions')
                  .prefetch_related('user_set')
910
                  .prefetch_related('user_set__facture_set__vente_set__cotisation')
911
912
913
                 ):
        rights[right] = (right.user_set
                         .annotate(action_number=Count('revision'),
914
915
                                   last_seen=Max('revision__date_created'),
                                   end_adhesion=Max('facture__vente__cotisation__date_end'))
916
917
918
919
                        )
    superusers = (User.objects
                  .filter(is_superuser=True)
                  .annotate(action_number=Count('revision'),
920
921
                            last_seen=Max('revision__date_created'),
                            end_adhesion=Max('facture__vente__cotisation__date_end'))
922
                 )
923
924
925
    return render(
        request,
        'users/index_listright.html',
Hugo LEVY-FALK's avatar
Hugo LEVY-FALK committed
926
        {
927
928
            'rights': rights,
            'superusers' : superusers,
Hugo LEVY-FALK's avatar
Hugo LEVY-FALK committed
929
        }
930
931
    )

932

933
@login_required
934
@can_view_all(ServiceUser)
935
936
937
def index_serviceusers(request):
    """ Affiche les users de services (pour les accès ldap)"""
    serviceusers_list = ServiceUser.objects.order_by('pseudo')
938
939
940
941
942
943
    return render(
        request,
        'users/index_serviceusers.html',
        {'serviceusers_list': serviceusers_list}
    )

944