views.py 29.8 KB
Newer Older
lhark's avatar
lhark committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 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
23
# App de gestion des users pour re2o
Dalahro's avatar
Dalahro committed
24
# Goulven Kermarec, Gabriel Détraz, Lemesle Augustin
chirac's avatar
chirac committed
25
# Gplv2
26 27 28 29 30 31 32 33 34
"""
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
"""
35 36 37

from __future__ import unicode_literals

38
from django.urls import reverse
39
from django.shortcuts import get_object_or_404, render, redirect
40
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
41
from django.contrib import messages
42
from django.contrib.auth.decorators import login_required, permission_required
43
from django.db.models import ProtectedError, Q
44
from django.db import IntegrityError
45
from django.utils import timezone
46
from django.db import transaction
47 48 49 50 51
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

from rest_framework.renderers import JSONRenderer

lhark's avatar
lhark committed
52

root's avatar
root committed
53
from reversion.models import Version
54
from reversion import revisions as reversion
55
from users.serializers import MailSerializer
56 57 58 59 60 61 62 63 64
from users.models import (
    User,
    Ban,
    Whitelist,
    School,
    ListRight,
    Request,
    ServiceUser,
    Adherent,
LEVY-FALK Hugo's avatar
LEVY-FALK Hugo committed
65
    Club,
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
)
from users.forms import (
    BanForm,
    WhitelistForm,
    DelSchoolForm,
    DelListRightForm,
    NewListRightForm,
    StateForm,
    SchoolForm,
    EditServiceUserForm,
    ServiceUserForm,
    ListRightForm,
    AdherentForm,
    ClubForm,
    MassArchiveForm,
    PassForm,
    ResetPasswordForm,
83 84
    ClubAdminandMembersForm,
    GroupForm
85
)
86 87 88
from cotisations.models import Facture
from machines.models import Machine
from preferences.models import OptionalUser, GeneralOption
chirac's avatar
chirac committed
89

90
from re2o.views import form
91
from re2o.utils import (
92 93
    all_has_access,
    SortTable,
94 95
)
from re2o.acl import (
96 97 98 99 100 101 102
    can_create,
    can_edit,
    can_delete_set,
    can_delete,
    can_view,
    can_view_all,
    can_change
103
)
104

105 106
def password_change_action(u_form, user, request, req=False):
    """ Fonction qui effectue le changeemnt de mdp bdd"""
107
    user.set_user_password(u_form.cleaned_data['passwd1'])
108 109 110
    with transaction.atomic(), reversion.create_revision():
        user.save()
        reversion.set_comment("Réinitialisation du mot de passe")
111 112 113
    messages.success(request, "Le mot de passe a changé")
    if req:
        req.delete()
114
        return redirect(reverse('index'))
115 116 117 118
    return redirect(reverse(
        'users:profil',
        kwargs={'userid':str(user.id)}
        ))
119

120
@can_create(Adherent)
chirac's avatar
chirac committed
121
def new_user(request):
122 123
    """ Vue de création d'un nouvel utilisateur,
    envoie un mail pour le mot de passe"""
124
    user = AdherentForm(request.POST or None, user=request.user)
125 126 127
    options, _created = GeneralOption.objects.get_or_create()
    GTU_sum_up = options.GTU_sum_up
    GTU = options.GTU
128
    if user.is_valid():
129
        user = user.save(commit=False)
130 131 132 133
        with transaction.atomic(), reversion.create_revision():
            user.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
134
        user.reset_passwd_mail(request)
135 136
        messages.success(request, "L'utilisateur %s a été crée, un mail\
        pour l'initialisation du mot de passe a été envoyé" % user.pseudo)
137 138 139 140
        return redirect(reverse(
            'users:profil',
            kwargs={'userid':str(user.id)}
            ))
141
    return form({'userform': user,'GTU_sum_up':GTU_sum_up,'GTU':GTU}, 'users/user.html', request)
142

143

144
@login_required
145
@can_create(Club)
146 147 148
def new_club(request):
    """ Vue de création d'un nouveau club,
    envoie un mail pour le mot de passe"""
149
    club = ClubForm(request.POST or None, user=request.user)
150 151 152 153 154 155 156 157 158
    if club.is_valid():
        club = club.save(commit=False)
        with transaction.atomic(), reversion.create_revision():
            club.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
        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)
159 160 161 162
        return redirect(reverse(
            'users:profil',
            kwargs={'userid':str(club.id)}
            ))
163 164 165
    return form({'userform': club}, 'users/user.html', request)


166
@login_required
167 168
@can_edit(Club)
def edit_club_admin_members(request, club_instance, clubid):
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
    """Vue d'edition de la liste des users administrateurs et
    membres d'un club"""
    club = ClubAdminandMembersForm(request.POST or None, instance=club_instance)
    if club.is_valid():
        with transaction.atomic(), reversion.create_revision():
            club.save()
            reversion.set_user(request.user)
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in club.changed_data
            ))
        messages.success(request, "Le club a bien été modifié")
        return redirect(reverse(
            'users:profil',
            kwargs={'userid':str(club_instance.id)}
            ))
    return form({'userform': club}, 'users/user.html', request)


chirac's avatar
chirac committed
187
@login_required
188
@can_edit(User)
189
def edit_info(request, user, userid):
190 191 192
    """ Edite un utilisateur à partir de son id,
    si l'id est différent de request.user, vérifie la
    possession du droit cableur """
193 194 195 196 197 198 199 200 201 202 203 204
    if user.is_class_adherent:
        user = AdherentForm(
            request.POST or None,
            instance=user.adherent,
            user=request.user
        )
    elif user.is_class_club:
        user = ClubForm(
            request.POST or None,
            instance=user.club,
            user=request.user
        )
205
    if user.is_valid():
206 207 208
        with transaction.atomic(), reversion.create_revision():
            user.save()
            reversion.set_user(request.user)
209 210 211
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in user.changed_data
            ))
212
        messages.success(request, "L'user a bien été modifié")
213 214 215 216
        return redirect(reverse(
            'users:profil',
            kwargs={'userid':str(userid)}
            ))
217
    return form({'userform': user}, 'users/user.html', request)
218

219

chirac's avatar
chirac committed
220
@login_required
221
@can_edit(User, 'state')
222
def state(request, user, userid):
223 224
    """ Changer l'etat actif/desactivé/archivé d'un user,
    need droit bureau """
225 226
    state = StateForm(request.POST or None, instance=user)
    if state.is_valid():
227
        with transaction.atomic(), reversion.create_revision():
228 229 230 231 232 233
            if state.cleaned_data['state'] == User.STATE_ARCHIVE:
                user.archive()
            elif state.cleaned_data['state'] == User.STATE_ACTIVE:
                user.unarchive()
            elif state.cleaned_data['state'] == User.STATE_DISABLED:
                user.state = User.STATE_DISABLED
234
            reversion.set_user(request.user)
235 236 237
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in state.changed_data
            ))
238
            user.save()
239
        messages.success(request, "Etat changé avec succès")
240 241 242 243
        return redirect(reverse(
            'users:profil',
            kwargs={'userid':str(userid)}
            ))
244
    return form({'userform': state}, 'users/user.html', request)
245

246

247
@login_required
248
@can_edit(User, 'groups')
249 250 251 252
def groups(request, user, userid):
    group = GroupForm(request.POST or None, instance=user)
    if group.is_valid():
        with transaction.atomic(), reversion.create_revision():
253 254 255
            reversion.set_user(request.user)
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in group.changed_data
256
            ))
257 258 259 260 261 262
        group.save()
        messages.success(request, "Groupes changés avec succès")
        return redirect(reverse(
            'users:profil',
            kwargs={'userid':str(userid)}
        ))
263 264 265
    return form({'userform': group}, 'users/user.html', request)


chirac's avatar
chirac committed
266
@login_required
267
@can_edit(User, 'password')
268
def password(request, user, userid):
chirac's avatar
chirac committed
269 270 271
    """ 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 """
272 273
    u_form = PassForm(request.POST or None)
    if u_form.is_valid():
274
        return password_change_action(u_form, user, request)
275
    return form({'userform': u_form}, 'users/user.html', request)
chirac's avatar
chirac committed
276

277

278
@login_required
279
@can_edit(User, 'groups')
280 281 282 283 284 285 286 287
def del_group(request, user, userid, listrightid):
    with transaction.atomic(), reversion.create_revision():
        user.groups.remove(ListRight.objects.get(id=listrightid))
        user.save()
        messages.success(request, "Droit supprimé à %s" % user)
    return redirect(reverse('users:index-listright'))


288
@login_required
289
@can_create(ServiceUser)
290 291 292 293 294 295 296 297 298 299
def new_serviceuser(request):
    """ Vue de création d'un nouvel utilisateur service"""
    user = ServiceUserForm(request.POST or None)
    if user.is_valid():
        user_object = user.save(commit=False)
        with transaction.atomic(), reversion.create_revision():
            user_object.set_password(user.cleaned_data['password'])
            user_object.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
300 301 302 303
        messages.success(
            request,
            "L'utilisateur %s a été crée" % user_object.pseudo
        )
304
        return redirect(reverse('users:index-serviceusers'))
305 306
    return form({'userform': user}, 'users/user.html', request)

307

308
@login_required
309 310 311
@can_edit(ServiceUser)
def edit_serviceuser(request, user, userid):
    """ Edit a ServiceUser """
312 313 314 315 316 317 318 319
    user = EditServiceUserForm(request.POST or None, instance=user)
    if user.is_valid():
        user_object = user.save(commit=False)
        with transaction.atomic(), reversion.create_revision():
            if user.cleaned_data['password']:
                user_object.set_password(user.cleaned_data['password'])
            user_object.save()
            reversion.set_user(request.user)
320 321 322
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in user.changed_data
            ))
323
        messages.success(request, "L'user a bien été modifié")
324
        return redirect(reverse('users:index-serviceusers'))
325 326
    return form({'userform': user}, 'users/user.html', request)

327

328
@login_required
329 330
@can_delete(ServiceUser)
def del_serviceuser(request, user, userid):
331
    """Suppression d'un ou plusieurs serviceusers"""
332 333 334 335 336
    if request.method == "POST":
        with transaction.atomic(), reversion.create_revision():
            user.delete()
            reversion.set_user(request.user)
        messages.success(request, "L'user a été détruite")
337
        return redirect(reverse('users:index-serviceusers'))
338 339 340 341 342 343
    return form(
        {'objet': user, 'objet_name': 'serviceuser'},
        'users/delete.html',
        request
    )

344

chirac's avatar
chirac committed
345
@login_required
346 347 348
@can_create(Ban)
@can_edit(User)
def add_ban(request, user, userid):
349 350
    """ Ajouter un banissement, nécessite au moins le droit bofh
    (a fortiori bureau)
chirac's avatar
chirac committed
351
    Syntaxe : JJ/MM/AAAA , heure optionnelle, prend effet immédiatement"""
352 353 354
    ban_instance = Ban(user=user)
    ban = BanForm(request.POST or None, instance=ban_instance)
    if ban.is_valid():
355
        with transaction.atomic(), reversion.create_revision():
356
            _ban_object = ban.save()
357 358
            reversion.set_user(request.user)
            reversion.set_comment("Création")
359
        messages.success(request, "Bannissement ajouté")
360 361 362 363
        return redirect(reverse(
            'users:profil',
            kwargs={'userid':str(userid)}
        ))
364
    if user.is_ban():
365 366 367 368
        messages.error(
            request,
            "Attention, cet utilisateur a deja un bannissement actif"
        )
369 370
    return form({'userform': ban}, 'users/user.html', request)

chirac's avatar
chirac committed
371
@login_required
372 373
@can_edit(Ban)
def edit_ban(request, ban_instance, banid):
374 375
    """ Editer un bannissement, nécessite au moins le droit bofh
    (a fortiori bureau)
chirac's avatar
chirac committed
376
    Syntaxe : JJ/MM/AAAA , heure optionnelle, prend effet immédiatement"""
377 378
    ban = BanForm(request.POST or None, instance=ban_instance)
    if ban.is_valid():
379 380 381
        with transaction.atomic(), reversion.create_revision():
            ban.save()
            reversion.set_user(request.user)
382 383 384
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in ban.changed_data
            ))
385
        messages.success(request, "Bannissement modifié")
386
        return redirect(reverse('users:index'))
387 388
    return form({'userform': ban}, 'users/user.html', request)

389

chirac's avatar
chirac committed
390
@login_required
391 392 393
@can_create(Whitelist)
@can_edit(User)
def add_whitelist(request, user, userid):
394 395 396 397
    """ 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
398
    whitelist_instance = Whitelist(user=user)
399 400 401 402
    whitelist = WhitelistForm(
        request.POST or None,
        instance=whitelist_instance
    )
chirac's avatar
chirac committed
403
    if whitelist.is_valid():
404 405 406 407
        with transaction.atomic(), reversion.create_revision():
            whitelist.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
chirac's avatar
chirac committed
408
        messages.success(request, "Accès à titre gracieux accordé")
409 410 411 412
        return redirect(reverse(
            'users:profil',
            kwargs={'userid':str(userid)}
            ))
413
    if user.is_whitelisted():
414 415 416 417
        messages.error(
            request,
            "Attention, cet utilisateur a deja un accès gracieux actif"
        )
chirac's avatar
chirac committed
418 419
    return form({'userform': whitelist}, 'users/user.html', request)

420

chirac's avatar
chirac committed
421
@login_required
422 423
@can_edit(Whitelist)
def edit_whitelist(request, whitelist_instance, whitelistid):
424 425 426 427 428 429 430 431
    """ 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
432
    if whitelist.is_valid():
433 434 435
        with transaction.atomic(), reversion.create_revision():
            whitelist.save()
            reversion.set_user(request.user)
436 437 438
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in whitelist.changed_data
            ))
chirac's avatar
chirac committed
439
        messages.success(request, "Whitelist modifiée")
440
        return redirect(reverse('users:index'))
chirac's avatar
chirac committed
441 442
    return form({'userform': whitelist}, 'users/user.html', request)

443

chirac's avatar
chirac committed
444
@login_required
445
@can_create(School)
chirac's avatar
chirac committed
446
def add_school(request):
447 448
    """ Ajouter un établissement d'enseignement à la base de donnée,
    need cableur"""
chirac's avatar
chirac committed
449 450
    school = SchoolForm(request.POST or None)
    if school.is_valid():
451 452 453 454
        with transaction.atomic(), reversion.create_revision():
            school.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
chirac's avatar
chirac committed
455
        messages.success(request, "L'établissement a été ajouté")
456
        return redirect(reverse('users:index-school'))
457
    return form({'userform': school}, 'users/user.html', request)
chirac's avatar
chirac committed
458

459

chirac's avatar
chirac committed
460
@login_required
461 462
@can_edit(School)
def edit_school(request, school_instance, schoolid):
463 464
    """ Editer un établissement d'enseignement à partir du schoolid dans
    la base de donnée, need cableur"""
465 466
    school = SchoolForm(request.POST or None, instance=school_instance)
    if school.is_valid():
467 468 469
        with transaction.atomic(), reversion.create_revision():
            school.save()
            reversion.set_user(request.user)
470 471 472
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in school.changed_data
            ))
473
        messages.success(request, "Établissement modifié")
474
        return redirect(reverse('users:index-school'))
475 476
    return form({'userform': school}, 'users/user.html', request)

477

chirac's avatar
chirac committed
478
@login_required
479
@can_delete_set(School)
480
def del_school(request, instances):
481 482 483 484
    """ 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 """
485
    school = DelSchoolForm(request.POST or None, instances=instances)
chirac's avatar
chirac committed
486 487 488 489
    if school.is_valid():
        school_dels = school.cleaned_data['schools']
        for school_del in school_dels:
            try:
490 491 492
                with transaction.atomic(), reversion.create_revision():
                    school_del.delete()
                    reversion.set_comment("Destruction")
chirac's avatar
chirac committed
493 494
                messages.success(request, "L'établissement a été supprimé")
            except ProtectedError:
495 496 497
                messages.error(
                    request,
                    "L'établissement %s est affecté à au moins un user, \
lhark's avatar
lhark committed
498
                        vous ne pouvez pas le supprimer" % school_del)
499
        return redirect(reverse('users:index-school'))
chirac's avatar
chirac committed
500 501
    return form({'userform': school}, 'users/user.html', request)

502

503
@login_required
504
@can_create(ListRight)
505
def add_listright(request):
chirac's avatar
chirac committed
506 507
    """ Ajouter un droit/groupe, nécessite droit bureau.
    Obligation de fournir un gid pour la synchro ldap, unique """
508 509 510 511 512 513 514
    listright = NewListRightForm(request.POST or None)
    if listright.is_valid():
        with transaction.atomic(), reversion.create_revision():
            listright.save()
            reversion.set_user(request.user)
            reversion.set_comment("Création")
        messages.success(request, "Le droit/groupe a été ajouté")
515
        return redirect(reverse('users:index-listright'))
516 517
    return form({'userform': listright}, 'users/user.html', request)

518

519
@login_required
520 521
@can_edit(ListRight)
def edit_listright(request, listright_instance, listrightid):
522 523 524 525 526 527
    """ Editer un groupe/droit, necessite droit bureau,
    à partir du listright id """
    listright = ListRightForm(
        request.POST or None,
        instance=listright_instance
    )
528 529 530 531
    if listright.is_valid():
        with transaction.atomic(), reversion.create_revision():
            listright.save()
            reversion.set_user(request.user)
532 533 534
            reversion.set_comment("Champs modifié(s) : %s" % ', '.join(
                field for field in listright.changed_data
            ))
535
        messages.success(request, "Droit modifié")
536
        return redirect(reverse('users:index-listright'))
537 538
    return form({'userform': listright}, 'users/user.html', request)

539

540
@login_required
541
@can_delete_set(ListRight)
542
def del_listright(request, instances):
543 544
    """ Supprimer un ou plusieurs groupe, possible si il est vide, need droit
    bureau """
545
    listright = DelListRightForm(request.POST or None, instances=instances)
546 547 548 549 550 551 552 553 554 555 556
    if listright.is_valid():
        listright_dels = listright.cleaned_data['listrights']
        for listright_del in listright_dels:
            try:
                with transaction.atomic(), reversion.create_revision():
                    listright_del.delete()
                    reversion.set_comment("Destruction")
                messages.success(request, "Le droit/groupe a été supprimé")
            except ProtectedError:
                messages.error(
                    request,
557
                    "Le groupe %s est affecté à au moins un user, \
558
                        vous ne pouvez pas le supprimer" % listright_del)
559
        return redirect(reverse('users:index-listright'))
560 561
    return form({'userform': listright}, 'users/user.html', request)

562

563
@login_required
564 565
@can_view_all(User)
@can_change(User, 'state')
566 567 568 569 570 571
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']
572 573 574 575
        to_archive_list = [user for user in
                           User.objects.exclude(state=User.STATE_ARCHIVE)
                           if not user.end_access()
                           or user.end_access() < date]
576 577 578
        if "valider" in request.POST:
            for user in to_archive_list:
                with transaction.atomic(), reversion.create_revision():
579
                    user.archive()
580
                    user.save()
581
                    reversion.set_user(request.user)
582
                    reversion.set_comment("Archivage")
583 584 585
            messages.success(request, "%s users ont été archivés" % len(
                to_archive_list
            ))
586
            return redirect(reverse('users:index'))
587 588 589 590 591 592
    return form(
        {'userform': to_archive_date, 'to_archive_list': to_archive_list},
        'users/mass_archive.html',
        request
    )

593

chirac's avatar
chirac committed
594
@login_required
595
@can_view_all(Adherent)
chirac's avatar
chirac committed
596
def index(request):
597
    """ Affiche l'ensemble des adherents, need droit cableur """
598
    options, _created = GeneralOption.objects.get_or_create()
599
    pagination_number = options.pagination_number
600
    users_list = Adherent.objects.select_related('room')
601 602 603 604 605 606
    users_list = SortTable.sort(
        users_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX
    )
607
    paginator = Paginator(users_list, pagination_number)
608 609 610 611 612 613 614 615 616
    page = request.GET.get('page')
    try:
        users_list = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        users_list = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        users_list = paginator.page(paginator.num_pages)
617
    return render(request, 'users/index.html', {'users_list': users_list})
root's avatar
root committed
618

619

620
@login_required
621
@can_view_all(Club)
622 623 624 625
def index_clubs(request):
    """ Affiche l'ensemble des clubs, need droit cableur """
    options, _created = GeneralOption.objects.get_or_create()
    pagination_number = options.pagination_number
626
    clubs_list = Club.objects.select_related('room')
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
    clubs_list = SortTable.sort(
        clubs_list,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX
    )
    paginator = Paginator(clubs_list, pagination_number)
    page = request.GET.get('page')
    try:
        clubs_list = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        clubs_list = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        clubs_list = paginator.page(paginator.num_pages)
    return render(request, 'users/index_clubs.html', {'clubs_list': clubs_list})


chirac's avatar
chirac committed
646
@login_required
647
@can_view_all(Ban)
648
def index_ban(request):
chirac's avatar
chirac committed
649
    """ Affiche l'ensemble des ban, need droit cableur """
650
    options, _created = GeneralOption.objects.get_or_create()
651
    pagination_number = options.pagination_number
652 653 654 655 656 657 658
    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
    )
659
    paginator = Paginator(ban_list, pagination_number)
660 661 662 663 664 665 666
    page = request.GET.get('page')
    try:
        ban_list = paginator.page(page)
    except PageNotAnInteger:
        # If page isn't an integer, deliver first page
        ban_list = paginator.page(1)
    except EmptyPage:
667 668
        # If page is out of range (e.g. 9999), deliver last page of results.
        ban_list = paginator.page(paginator.num_pages)
669
    return render(request, 'users/index_ban.html', {'ban_list': ban_list})
670

671

chirac's avatar
chirac committed
672
@login_required
673
@can_view_all(Whitelist)
674
def index_white(request):
chirac's avatar
chirac committed
675
    """ Affiche l'ensemble des whitelist, need droit cableur """
676
    options, _created = GeneralOption.objects.get_or_create()
677
    pagination_number = options.pagination_number
678 679 680 681 682 683 684
    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
    )
685 686 687 688 689 690 691 692
    paginator = Paginator(white_list, pagination_number)
    page = request.GET.get('page')
    try:
        white_list = paginator.page(page)
    except PageNotAnInteger:
        # If page isn't an integer, deliver first page
        white_list = paginator.page(1)
    except EmptyPage:
693 694
        # If page is out of range (e.g. 9999), deliver last page of results.
        white_list = paginator.page(paginator.num_pages)
695 696 697 698 699 700
    return render(
        request,
        'users/index_whitelist.html',
        {'white_list': white_list}
    )

701

chirac's avatar
chirac committed
702
@login_required
703
@can_view_all(School)
704
def index_school(request):
chirac's avatar
chirac committed
705
    """ Affiche l'ensemble des établissement, need droit cableur """
706
    school_list = School.objects.order_by('name')
707 708 709 710 711 712
    return render(
        request,
        'users/index_schools.html',
        {'school_list': school_list}
    )

713

714
@login_required
715
@can_view_all(ListRight)
716
def index_listright(request):
chirac's avatar
chirac committed
717
    """ Affiche l'ensemble des droits , need droit cableur """
718
    listright_list = ListRight.objects.order_by('unix_name')
719 720 721 722 723 724
    return render(
        request,
        'users/index_listright.html',
        {'listright_list': listright_list}
    )

725

726
@login_required
727
@can_view_all(ServiceUser)
728 729 730
def index_serviceusers(request):
    """ Affiche les users de services (pour les accès ldap)"""
    serviceusers_list = ServiceUser.objects.order_by('pseudo')
731 732 733 734 735 736
    return render(
        request,
        'users/index_serviceusers.html',
        {'serviceusers_list': serviceusers_list}
    )

737

738 739
@login_required
def mon_profil(request):
chirac's avatar
chirac committed
740
    """ Lien vers profil, renvoie request.id à la fonction """
741 742 743 744
    return redirect(reverse(
        'users:profil',
        kwargs={'userid':str(request.user.id)}
        ))
745

746

chirac's avatar
chirac committed
747
@login_required
748 749
@can_view(User)
def profil(request, users, userid):
chirac's avatar
chirac committed
750
    """ Affiche un profil, self or cableur, prend un userid en argument """
751 752 753 754 755
    machines = Machine.objects.filter(user=users).select_related('user')\
        .prefetch_related('interface_set__domain__extension')\
        .prefetch_related('interface_set__ipv4__ip_type__extension')\
        .prefetch_related('interface_set__type')\
        .prefetch_related('interface_set__domain__related_domain__extension')
756 757 758 759 760 761
    machines = SortTable.sort(
        machines,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.MACHINES_INDEX
    )
chirac's avatar
chirac committed
762
    factures = Facture.objects.filter(user=users)
763 764 765 766 767 768
    factures = SortTable.sort(
        factures,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.COTISATIONS_INDEX
    )
chirac's avatar
chirac committed
769
    bans = Ban.objects.filter(user=users)
770 771 772 773 774 775
    bans = SortTable.sort(
        bans,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX_BAN
    )
chirac's avatar
chirac committed
776
    whitelists = Whitelist.objects.filter(user=users)
777 778 779 780 781 782
    whitelists = SortTable.sort(
        whitelists,
        request.GET.get('col'),
        request.GET.get('order'),
        SortTable.USERS_INDEX_WHITE
    )
783
    options, _created = OptionalUser.objects.get_or_create()
chibrac's avatar
chibrac committed
784
    user_solde = options.user_solde
785 786 787 788
    return render(
        request,
        'users/profil.html',
        {
789
            'users': users,
790
            'machines_list': machines,
791 792 793
            'facture_list': factures,
            'ban_list': bans,
            'white_list': whitelists,
chibrac's avatar
chibrac committed
794
            'user_solde': user_solde,
lhark's avatar
lhark committed
795 796
        }
    )
root's avatar
root committed
797

798

chirac's avatar
chirac committed
799
def reset_password(request):
chirac's avatar
chirac committed
800
    """ Reintialisation du mot de passe si mdp oublié """
chirac's avatar
chirac committed
801 802 803
    userform = ResetPasswordForm(request.POST or None)
    if userform.is_valid():
        try:
804 805 806 807
            user = User.objects.get(
                pseudo=userform.cleaned_data['pseudo'],
                email=userform.cleaned_data['email']
            )
chirac's avatar
chirac committed
808 809
        except User.DoesNotExist:
            messages.error(request, "Cet utilisateur n'existe pas")
810 811
            return form({'userform': userform}, 'users/user.html', request)
        user.reset_passwd_mail(request)
812 813
        messages.success(request, "Un mail pour l'initialisation du mot\
        de passe a été envoyé")
814
        redirect(reverse('index'))
chirac's avatar
chirac committed
815 816
    return form({'userform': userform}, 'users/user.html', request)

817

818
def process(request, token):
819
    """Process, lien pour la reinitialisation du mot de passe"""
820 821 822 823 824 825
    valid_reqs = Request.objects.filter(expires_at__gt=timezone.now())
    req = get_object_or_404(valid_reqs, token=token)

    if req.type == Request.PASSWD:
        return process_passwd(request, req)
    else:
chirac's avatar
chirac committed
826
        messages.error(request, "Entrée incorrecte, contactez un admin")
827
        redirect(reverse('index'))
828

829

830
def process_passwd(request, req):
831 832
    """Process le changeemnt de mot de passe, renvoie le formulaire
    demandant le nouveau password"""
833 834 835 836 837
    u_form = PassForm(request.POST or None)
    user = req.user
    if u_form.is_valid():
        return password_change_action(u_form, user, request, req=req)
    return form({'userform': u_form}, 'users/user.html', request)
838

839 840

class JSONResponse(HttpResponse):
841
    """ Framework Rest """
842 843 844 845 846
    def __init__(self, data, **kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)

847

848 849 850 851
@csrf_exempt
@login_required
@permission_required('serveur')
def mailing(request):
chirac's avatar
chirac committed
852 853
    """ Fonction de serialisation des addresses mail de tous les users
    Pour generation de ml all users"""
854
    mails = all_has_access().values('email').distinct()
855 856
    seria = MailSerializer(mails, many=True)
    return JSONResponse(seria.data)